Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Kitware
GitHub Repository: Kitware/CMake
Path: blob/master/Utilities/cmbzip2/bzlib.c
3148 views
1
2
/*-------------------------------------------------------------*/
3
/*--- Library top-level functions. ---*/
4
/*--- bzlib.c ---*/
5
/*-------------------------------------------------------------*/
6
7
/* ------------------------------------------------------------------
8
This file is part of bzip2/libbzip2, a program and library for
9
lossless, block-sorting data compression.
10
11
bzip2/libbzip2 version 1.0.8 of 13 July 2019
12
Copyright (C) 1996-2019 Julian Seward <[email protected]>
13
14
Please read the WARNING, DISCLAIMER and PATENTS sections in the
15
README file.
16
17
This program is released under the terms of the license contained
18
in the file LICENSE.
19
------------------------------------------------------------------ */
20
21
/* CHANGES
22
0.9.0 -- original version.
23
0.9.0a/b -- no changes in this file.
24
0.9.0c -- made zero-length BZ_FLUSH work correctly in bzCompress().
25
fixed bzWrite/bzRead to ignore zero-length requests.
26
fixed bzread to correctly handle read requests after EOF.
27
wrong parameter order in call to bzDecompressInit in
28
bzBuffToBuffDecompress. Fixed.
29
*/
30
31
#include "bzlib_private.h"
32
33
34
/*---------------------------------------------------*/
35
/*--- Compression stuff ---*/
36
/*---------------------------------------------------*/
37
38
39
/*---------------------------------------------------*/
40
#ifndef BZ_NO_STDIO
41
void BZ2_bz__AssertH__fail ( int errcode )
42
{
43
fprintf(stderr,
44
"\n\nbzip2/libbzip2: internal error number %d.\n"
45
"This is a bug in bzip2/libbzip2, %s.\n"
46
"Please report it to: [email protected]. If this happened\n"
47
"when you were using some program which uses libbzip2 as a\n"
48
"component, you should also report this bug to the author(s)\n"
49
"of that program. Please make an effort to report this bug;\n"
50
"timely and accurate bug reports eventually lead to higher\n"
51
"quality software. Thanks.\n\n",
52
errcode,
53
BZ2_bzlibVersion()
54
);
55
56
if (errcode == 1007) {
57
fprintf(stderr,
58
"\n*** A special note about internal error number 1007 ***\n"
59
"\n"
60
"Experience suggests that a common cause of i.e. 1007\n"
61
"is unreliable memory or other hardware. The 1007 assertion\n"
62
"just happens to cross-check the results of huge numbers of\n"
63
"memory reads/writes, and so acts (unintendedly) as a stress\n"
64
"test of your memory system.\n"
65
"\n"
66
"I suggest the following: try compressing the file again,\n"
67
"possibly monitoring progress in detail with the -vv flag.\n"
68
"\n"
69
"* If the error cannot be reproduced, and/or happens at different\n"
70
" points in compression, you may have a flaky memory system.\n"
71
" Try a memory-test program. I have used Memtest86\n"
72
" (www.memtest86.com). At the time of writing it is free (GPLd).\n"
73
" Memtest86 tests memory much more thorougly than your BIOSs\n"
74
" power-on test, and may find failures that the BIOS doesn't.\n"
75
"\n"
76
"* If the error can be repeatably reproduced, this is a bug in\n"
77
" bzip2, and I would very much like to hear about it. Please\n"
78
" let me know, and, ideally, save a copy of the file causing the\n"
79
" problem -- without which I will be unable to investigate it.\n"
80
"\n"
81
);
82
}
83
84
exit(3);
85
}
86
#endif
87
88
89
/*---------------------------------------------------*/
90
static
91
int bz_config_ok ( void )
92
{
93
if (sizeof(int) != 4) return 0;
94
if (sizeof(short) != 2) return 0;
95
if (sizeof(char) != 1) return 0;
96
return 1;
97
}
98
99
100
/*---------------------------------------------------*/
101
static
102
void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
103
{
104
void* v = malloc ( items * size );
105
return v;
106
}
107
108
static
109
void default_bzfree ( void* opaque, void* addr )
110
{
111
if (addr != NULL) free ( addr );
112
}
113
114
115
/*---------------------------------------------------*/
116
static
117
void prepare_new_block ( EState* s )
118
{
119
Int32 i;
120
s->nblock = 0;
121
s->numZ = 0;
122
s->state_out_pos = 0;
123
BZ_INITIALISE_CRC ( s->blockCRC );
124
for (i = 0; i < 256; i++) s->inUse[i] = False;
125
s->blockNo++;
126
}
127
128
129
/*---------------------------------------------------*/
130
static
131
void init_RL ( EState* s )
132
{
133
s->state_in_ch = 256;
134
s->state_in_len = 0;
135
}
136
137
138
static
139
Bool isempty_RL ( EState* s )
140
{
141
if (s->state_in_ch < 256 && s->state_in_len > 0)
142
return False; else
143
return True;
144
}
145
146
147
/*---------------------------------------------------*/
148
int BZ_API(BZ2_bzCompressInit)
149
( bz_stream* strm,
150
int blockSize100k,
151
int verbosity,
152
int workFactor )
153
{
154
Int32 n;
155
EState* s;
156
157
if (!bz_config_ok()) return BZ_CONFIG_ERROR;
158
159
if (strm == NULL ||
160
blockSize100k < 1 || blockSize100k > 9 ||
161
workFactor < 0 || workFactor > 250)
162
return BZ_PARAM_ERROR;
163
164
if (workFactor == 0) workFactor = 30;
165
if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
166
if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
167
168
s = BZALLOC( sizeof(EState) );
169
if (s == NULL) return BZ_MEM_ERROR;
170
s->strm = strm;
171
172
s->arr1 = NULL;
173
s->arr2 = NULL;
174
s->ftab = NULL;
175
176
n = 100000 * blockSize100k;
177
s->arr1 = BZALLOC( n * sizeof(UInt32) );
178
s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
179
s->ftab = BZALLOC( 65537 * sizeof(UInt32) );
180
181
if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
182
if (s->arr1 != NULL) BZFREE(s->arr1);
183
if (s->arr2 != NULL) BZFREE(s->arr2);
184
if (s->ftab != NULL) BZFREE(s->ftab);
185
if (s != NULL) BZFREE(s);
186
return BZ_MEM_ERROR;
187
}
188
189
s->blockNo = 0;
190
s->state = BZ_S_INPUT;
191
s->mode = BZ_M_RUNNING;
192
s->combinedCRC = 0;
193
s->blockSize100k = blockSize100k;
194
s->nblockMAX = 100000 * blockSize100k - 19;
195
s->verbosity = verbosity;
196
s->workFactor = workFactor;
197
198
s->block = (UChar*)s->arr2;
199
s->mtfv = (UInt16*)s->arr1;
200
s->zbits = NULL;
201
s->ptr = (UInt32*)s->arr1;
202
203
strm->state = s;
204
strm->total_in_lo32 = 0;
205
strm->total_in_hi32 = 0;
206
strm->total_out_lo32 = 0;
207
strm->total_out_hi32 = 0;
208
init_RL ( s );
209
prepare_new_block ( s );
210
return BZ_OK;
211
}
212
213
214
/*---------------------------------------------------*/
215
static
216
void add_pair_to_block ( EState* s )
217
{
218
Int32 i;
219
UChar ch = (UChar)(s->state_in_ch);
220
for (i = 0; i < s->state_in_len; i++) {
221
BZ_UPDATE_CRC( s->blockCRC, ch );
222
}
223
s->inUse[s->state_in_ch] = True;
224
switch (s->state_in_len) {
225
case 1:
226
s->block[s->nblock] = (UChar)ch; s->nblock++;
227
break;
228
case 2:
229
s->block[s->nblock] = (UChar)ch; s->nblock++;
230
s->block[s->nblock] = (UChar)ch; s->nblock++;
231
break;
232
case 3:
233
s->block[s->nblock] = (UChar)ch; s->nblock++;
234
s->block[s->nblock] = (UChar)ch; s->nblock++;
235
s->block[s->nblock] = (UChar)ch; s->nblock++;
236
break;
237
default:
238
s->inUse[s->state_in_len-4] = True;
239
s->block[s->nblock] = (UChar)ch; s->nblock++;
240
s->block[s->nblock] = (UChar)ch; s->nblock++;
241
s->block[s->nblock] = (UChar)ch; s->nblock++;
242
s->block[s->nblock] = (UChar)ch; s->nblock++;
243
s->block[s->nblock] = ((UChar)(s->state_in_len-4));
244
s->nblock++;
245
break;
246
}
247
}
248
249
250
/*---------------------------------------------------*/
251
static
252
void flush_RL ( EState* s )
253
{
254
if (s->state_in_ch < 256) add_pair_to_block ( s );
255
init_RL ( s );
256
}
257
258
259
/*---------------------------------------------------*/
260
#define ADD_CHAR_TO_BLOCK(zs,zchh0) \
261
{ \
262
UInt32 zchh = (UInt32)(zchh0); \
263
/*-- fast track the common case --*/ \
264
if (zchh != zs->state_in_ch && \
265
zs->state_in_len == 1) { \
266
UChar ch = (UChar)(zs->state_in_ch); \
267
BZ_UPDATE_CRC( zs->blockCRC, ch ); \
268
zs->inUse[zs->state_in_ch] = True; \
269
zs->block[zs->nblock] = (UChar)ch; \
270
zs->nblock++; \
271
zs->state_in_ch = zchh; \
272
} \
273
else \
274
/*-- general, uncommon cases --*/ \
275
if (zchh != zs->state_in_ch || \
276
zs->state_in_len == 255) { \
277
if (zs->state_in_ch < 256) \
278
add_pair_to_block ( zs ); \
279
zs->state_in_ch = zchh; \
280
zs->state_in_len = 1; \
281
} else { \
282
zs->state_in_len++; \
283
} \
284
}
285
286
287
/*---------------------------------------------------*/
288
static
289
Bool copy_input_until_stop ( EState* s )
290
{
291
Bool progress_in = False;
292
293
if (s->mode == BZ_M_RUNNING) {
294
295
/*-- fast track the common case --*/
296
while (True) {
297
/*-- block full? --*/
298
if (s->nblock >= s->nblockMAX) break;
299
/*-- no input? --*/
300
if (s->strm->avail_in == 0) break;
301
progress_in = True;
302
ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
303
s->strm->next_in++;
304
s->strm->avail_in--;
305
s->strm->total_in_lo32++;
306
if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
307
}
308
309
} else {
310
311
/*-- general, uncommon case --*/
312
while (True) {
313
/*-- block full? --*/
314
if (s->nblock >= s->nblockMAX) break;
315
/*-- no input? --*/
316
if (s->strm->avail_in == 0) break;
317
/*-- flush/finish end? --*/
318
if (s->avail_in_expect == 0) break;
319
progress_in = True;
320
ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
321
s->strm->next_in++;
322
s->strm->avail_in--;
323
s->strm->total_in_lo32++;
324
if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
325
s->avail_in_expect--;
326
}
327
}
328
return progress_in;
329
}
330
331
332
/*---------------------------------------------------*/
333
static
334
Bool copy_output_until_stop ( EState* s )
335
{
336
Bool progress_out = False;
337
338
while (True) {
339
340
/*-- no output space? --*/
341
if (s->strm->avail_out == 0) break;
342
343
/*-- block done? --*/
344
if (s->state_out_pos >= s->numZ) break;
345
346
progress_out = True;
347
*(s->strm->next_out) = s->zbits[s->state_out_pos];
348
s->state_out_pos++;
349
s->strm->avail_out--;
350
s->strm->next_out++;
351
s->strm->total_out_lo32++;
352
if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
353
}
354
355
return progress_out;
356
}
357
358
359
/*---------------------------------------------------*/
360
static
361
Bool handle_compress ( bz_stream* strm )
362
{
363
Bool progress_in = False;
364
Bool progress_out = False;
365
EState* s = strm->state;
366
367
while (True) {
368
369
if (s->state == BZ_S_OUTPUT) {
370
progress_out |= copy_output_until_stop ( s );
371
if (s->state_out_pos < s->numZ) break;
372
if (s->mode == BZ_M_FINISHING &&
373
s->avail_in_expect == 0 &&
374
isempty_RL(s)) break;
375
prepare_new_block ( s );
376
s->state = BZ_S_INPUT;
377
if (s->mode == BZ_M_FLUSHING &&
378
s->avail_in_expect == 0 &&
379
isempty_RL(s)) break;
380
}
381
382
if (s->state == BZ_S_INPUT) {
383
progress_in |= copy_input_until_stop ( s );
384
if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
385
flush_RL ( s );
386
BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
387
s->state = BZ_S_OUTPUT;
388
}
389
else
390
if (s->nblock >= s->nblockMAX) {
391
BZ2_compressBlock ( s, False );
392
s->state = BZ_S_OUTPUT;
393
}
394
else
395
if (s->strm->avail_in == 0) {
396
break;
397
}
398
}
399
400
}
401
402
return progress_in || progress_out;
403
}
404
405
406
/*---------------------------------------------------*/
407
int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
408
{
409
Bool progress;
410
EState* s;
411
if (strm == NULL) return BZ_PARAM_ERROR;
412
s = strm->state;
413
if (s == NULL) return BZ_PARAM_ERROR;
414
if (s->strm != strm) return BZ_PARAM_ERROR;
415
416
preswitch:
417
switch (s->mode) {
418
419
case BZ_M_IDLE:
420
return BZ_SEQUENCE_ERROR;
421
422
case BZ_M_RUNNING:
423
if (action == BZ_RUN) {
424
progress = handle_compress ( strm );
425
return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
426
}
427
else
428
if (action == BZ_FLUSH) {
429
s->avail_in_expect = strm->avail_in;
430
s->mode = BZ_M_FLUSHING;
431
goto preswitch;
432
}
433
else
434
if (action == BZ_FINISH) {
435
s->avail_in_expect = strm->avail_in;
436
s->mode = BZ_M_FINISHING;
437
goto preswitch;
438
}
439
else
440
return BZ_PARAM_ERROR;
441
442
case BZ_M_FLUSHING:
443
if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
444
if (s->avail_in_expect != s->strm->avail_in)
445
return BZ_SEQUENCE_ERROR;
446
progress = handle_compress ( strm );
447
#ifdef __clang_analyzer__
448
/* Tolerate deadcode.DeadStores to avoid modifying upstream. */
449
(void)progress;
450
#endif
451
if (s->avail_in_expect > 0 || !isempty_RL(s) ||
452
s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
453
s->mode = BZ_M_RUNNING;
454
return BZ_RUN_OK;
455
456
case BZ_M_FINISHING:
457
if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
458
if (s->avail_in_expect != s->strm->avail_in)
459
return BZ_SEQUENCE_ERROR;
460
progress = handle_compress ( strm );
461
if (!progress) return BZ_SEQUENCE_ERROR;
462
if (s->avail_in_expect > 0 || !isempty_RL(s) ||
463
s->state_out_pos < s->numZ) return BZ_FINISH_OK;
464
s->mode = BZ_M_IDLE;
465
return BZ_STREAM_END;
466
}
467
return BZ_OK; /*--not reached--*/
468
}
469
470
471
/*---------------------------------------------------*/
472
int BZ_API(BZ2_bzCompressEnd) ( bz_stream *strm )
473
{
474
EState* s;
475
if (strm == NULL) return BZ_PARAM_ERROR;
476
s = strm->state;
477
if (s == NULL) return BZ_PARAM_ERROR;
478
if (s->strm != strm) return BZ_PARAM_ERROR;
479
480
if (s->arr1 != NULL) BZFREE(s->arr1);
481
if (s->arr2 != NULL) BZFREE(s->arr2);
482
if (s->ftab != NULL) BZFREE(s->ftab);
483
BZFREE(strm->state);
484
485
strm->state = NULL;
486
487
return BZ_OK;
488
}
489
490
491
/*---------------------------------------------------*/
492
/*--- Decompression stuff ---*/
493
/*---------------------------------------------------*/
494
495
/*---------------------------------------------------*/
496
int BZ_API(BZ2_bzDecompressInit)
497
( bz_stream* strm,
498
int verbosity,
499
int small )
500
{
501
DState* s;
502
503
if (!bz_config_ok()) return BZ_CONFIG_ERROR;
504
505
if (strm == NULL) return BZ_PARAM_ERROR;
506
if (small != 0 && small != 1) return BZ_PARAM_ERROR;
507
if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
508
509
if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
510
if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
511
512
s = BZALLOC( sizeof(DState) );
513
if (s == NULL) return BZ_MEM_ERROR;
514
s->strm = strm;
515
strm->state = s;
516
s->state = BZ_X_MAGIC_1;
517
s->bsLive = 0;
518
s->bsBuff = 0;
519
s->calculatedCombinedCRC = 0;
520
strm->total_in_lo32 = 0;
521
strm->total_in_hi32 = 0;
522
strm->total_out_lo32 = 0;
523
strm->total_out_hi32 = 0;
524
s->smallDecompress = (Bool)small;
525
s->ll4 = NULL;
526
s->ll16 = NULL;
527
s->tt = NULL;
528
s->currBlockNo = 0;
529
s->verbosity = verbosity;
530
531
return BZ_OK;
532
}
533
534
535
/*---------------------------------------------------*/
536
/* Return True iff data corruption is discovered.
537
Returns False if there is no problem.
538
*/
539
static
540
Bool unRLE_obuf_to_output_FAST ( DState* s )
541
{
542
UChar k1;
543
544
if (s->blockRandomised) {
545
546
while (True) {
547
/* try to finish existing run */
548
while (True) {
549
if (s->strm->avail_out == 0) return False;
550
if (s->state_out_len == 0) break;
551
*( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
552
BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
553
s->state_out_len--;
554
s->strm->next_out++;
555
s->strm->avail_out--;
556
s->strm->total_out_lo32++;
557
if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
558
}
559
560
/* can a new run be started? */
561
if (s->nblock_used == s->save_nblock+1) return False;
562
563
/* Only caused by corrupt data stream? */
564
if (s->nblock_used > s->save_nblock+1)
565
return True;
566
567
s->state_out_len = 1;
568
s->state_out_ch = s->k0;
569
BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
570
k1 ^= BZ_RAND_MASK; s->nblock_used++;
571
if (s->nblock_used == s->save_nblock+1) continue;
572
if (k1 != s->k0) { s->k0 = k1; continue; };
573
574
s->state_out_len = 2;
575
BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
576
k1 ^= BZ_RAND_MASK; s->nblock_used++;
577
if (s->nblock_used == s->save_nblock+1) continue;
578
if (k1 != s->k0) { s->k0 = k1; continue; };
579
580
s->state_out_len = 3;
581
BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
582
k1 ^= BZ_RAND_MASK; s->nblock_used++;
583
if (s->nblock_used == s->save_nblock+1) continue;
584
if (k1 != s->k0) { s->k0 = k1; continue; };
585
586
BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
587
k1 ^= BZ_RAND_MASK; s->nblock_used++;
588
s->state_out_len = ((Int32)k1) + 4;
589
BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
590
s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
591
}
592
593
} else {
594
595
/* restore */
596
UInt32 c_calculatedBlockCRC = s->calculatedBlockCRC;
597
UChar c_state_out_ch = s->state_out_ch;
598
Int32 c_state_out_len = s->state_out_len;
599
Int32 c_nblock_used = s->nblock_used;
600
Int32 c_k0 = s->k0;
601
UInt32* c_tt = s->tt;
602
UInt32 c_tPos = s->tPos;
603
char* cs_next_out = s->strm->next_out;
604
unsigned int cs_avail_out = s->strm->avail_out;
605
Int32 ro_blockSize100k = s->blockSize100k;
606
/* end restore */
607
608
UInt32 avail_out_INIT = cs_avail_out;
609
Int32 s_save_nblockPP = s->save_nblock+1;
610
unsigned int total_out_lo32_old;
611
612
while (True) {
613
614
/* try to finish existing run */
615
if (c_state_out_len > 0) {
616
while (True) {
617
if (cs_avail_out == 0) goto return_notr;
618
if (c_state_out_len == 1) break;
619
*( (UChar*)(cs_next_out) ) = c_state_out_ch;
620
BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
621
c_state_out_len--;
622
cs_next_out++;
623
cs_avail_out--;
624
}
625
s_state_out_len_eq_one:
626
{
627
if (cs_avail_out == 0) {
628
c_state_out_len = 1; goto return_notr;
629
};
630
*( (UChar*)(cs_next_out) ) = c_state_out_ch;
631
BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
632
cs_next_out++;
633
cs_avail_out--;
634
}
635
}
636
/* Only caused by corrupt data stream? */
637
if (c_nblock_used > s_save_nblockPP)
638
return True;
639
640
/* can a new run be started? */
641
if (c_nblock_used == s_save_nblockPP) {
642
c_state_out_len = 0; goto return_notr;
643
};
644
c_state_out_ch = c_k0;
645
BZ_GET_FAST_C(k1); c_nblock_used++;
646
if (k1 != c_k0) {
647
c_k0 = k1; goto s_state_out_len_eq_one;
648
};
649
if (c_nblock_used == s_save_nblockPP)
650
goto s_state_out_len_eq_one;
651
652
c_state_out_len = 2;
653
BZ_GET_FAST_C(k1); c_nblock_used++;
654
if (c_nblock_used == s_save_nblockPP) continue;
655
if (k1 != c_k0) { c_k0 = k1; continue; };
656
657
c_state_out_len = 3;
658
BZ_GET_FAST_C(k1); c_nblock_used++;
659
if (c_nblock_used == s_save_nblockPP) continue;
660
if (k1 != c_k0) { c_k0 = k1; continue; };
661
662
BZ_GET_FAST_C(k1); c_nblock_used++;
663
c_state_out_len = ((Int32)k1) + 4;
664
BZ_GET_FAST_C(c_k0); c_nblock_used++;
665
}
666
667
return_notr:
668
total_out_lo32_old = s->strm->total_out_lo32;
669
s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
670
if (s->strm->total_out_lo32 < total_out_lo32_old)
671
s->strm->total_out_hi32++;
672
673
/* save */
674
s->calculatedBlockCRC = c_calculatedBlockCRC;
675
s->state_out_ch = c_state_out_ch;
676
s->state_out_len = c_state_out_len;
677
s->nblock_used = c_nblock_used;
678
s->k0 = c_k0;
679
s->tt = c_tt;
680
s->tPos = c_tPos;
681
s->strm->next_out = cs_next_out;
682
s->strm->avail_out = cs_avail_out;
683
/* end save */
684
}
685
return False;
686
}
687
688
689
690
/*---------------------------------------------------*/
691
__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
692
{
693
Int32 nb, na, mid;
694
nb = 0;
695
na = 256;
696
do {
697
mid = (nb + na) >> 1;
698
if (indx >= cftab[mid]) nb = mid; else na = mid;
699
}
700
while (na - nb != 1);
701
return nb;
702
}
703
704
705
/*---------------------------------------------------*/
706
/* Return True iff data corruption is discovered.
707
Returns False if there is no problem.
708
*/
709
static
710
Bool unRLE_obuf_to_output_SMALL ( DState* s )
711
{
712
UChar k1;
713
714
if (s->blockRandomised) {
715
716
while (True) {
717
/* try to finish existing run */
718
while (True) {
719
if (s->strm->avail_out == 0) return False;
720
if (s->state_out_len == 0) break;
721
*( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
722
BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
723
s->state_out_len--;
724
s->strm->next_out++;
725
s->strm->avail_out--;
726
s->strm->total_out_lo32++;
727
if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
728
}
729
730
/* can a new run be started? */
731
if (s->nblock_used == s->save_nblock+1) return False;
732
733
/* Only caused by corrupt data stream? */
734
if (s->nblock_used > s->save_nblock+1)
735
return True;
736
737
s->state_out_len = 1;
738
s->state_out_ch = s->k0;
739
BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
740
k1 ^= BZ_RAND_MASK; s->nblock_used++;
741
if (s->nblock_used == s->save_nblock+1) continue;
742
if (k1 != s->k0) { s->k0 = k1; continue; };
743
744
s->state_out_len = 2;
745
BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
746
k1 ^= BZ_RAND_MASK; s->nblock_used++;
747
if (s->nblock_used == s->save_nblock+1) continue;
748
if (k1 != s->k0) { s->k0 = k1; continue; };
749
750
s->state_out_len = 3;
751
BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
752
k1 ^= BZ_RAND_MASK; s->nblock_used++;
753
if (s->nblock_used == s->save_nblock+1) continue;
754
if (k1 != s->k0) { s->k0 = k1; continue; };
755
756
BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
757
k1 ^= BZ_RAND_MASK; s->nblock_used++;
758
s->state_out_len = ((Int32)k1) + 4;
759
BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
760
s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
761
}
762
763
} else {
764
765
while (True) {
766
/* try to finish existing run */
767
while (True) {
768
if (s->strm->avail_out == 0) return False;
769
if (s->state_out_len == 0) break;
770
*( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
771
BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
772
s->state_out_len--;
773
s->strm->next_out++;
774
s->strm->avail_out--;
775
s->strm->total_out_lo32++;
776
if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
777
}
778
779
/* can a new run be started? */
780
if (s->nblock_used == s->save_nblock+1) return False;
781
782
/* Only caused by corrupt data stream? */
783
if (s->nblock_used > s->save_nblock+1)
784
return True;
785
786
s->state_out_len = 1;
787
s->state_out_ch = s->k0;
788
BZ_GET_SMALL(k1); s->nblock_used++;
789
if (s->nblock_used == s->save_nblock+1) continue;
790
if (k1 != s->k0) { s->k0 = k1; continue; };
791
792
s->state_out_len = 2;
793
BZ_GET_SMALL(k1); s->nblock_used++;
794
if (s->nblock_used == s->save_nblock+1) continue;
795
if (k1 != s->k0) { s->k0 = k1; continue; };
796
797
s->state_out_len = 3;
798
BZ_GET_SMALL(k1); s->nblock_used++;
799
if (s->nblock_used == s->save_nblock+1) continue;
800
if (k1 != s->k0) { s->k0 = k1; continue; };
801
802
BZ_GET_SMALL(k1); s->nblock_used++;
803
s->state_out_len = ((Int32)k1) + 4;
804
BZ_GET_SMALL(s->k0); s->nblock_used++;
805
}
806
807
}
808
}
809
810
811
/*---------------------------------------------------*/
812
int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
813
{
814
Bool corrupt;
815
DState* s;
816
if (strm == NULL) return BZ_PARAM_ERROR;
817
s = strm->state;
818
if (s == NULL) return BZ_PARAM_ERROR;
819
if (s->strm != strm) return BZ_PARAM_ERROR;
820
821
while (True) {
822
if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
823
if (s->state == BZ_X_OUTPUT) {
824
if (s->smallDecompress)
825
corrupt = unRLE_obuf_to_output_SMALL ( s ); else
826
corrupt = unRLE_obuf_to_output_FAST ( s );
827
if (corrupt) return BZ_DATA_ERROR;
828
if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
829
BZ_FINALISE_CRC ( s->calculatedBlockCRC );
830
if (s->verbosity >= 3)
831
VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC,
832
s->calculatedBlockCRC );
833
if (s->verbosity >= 2) VPrintf0 ( "]" );
834
if (s->calculatedBlockCRC != s->storedBlockCRC)
835
return BZ_DATA_ERROR;
836
s->calculatedCombinedCRC
837
= (s->calculatedCombinedCRC << 1) |
838
(s->calculatedCombinedCRC >> 31);
839
s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
840
s->state = BZ_X_BLKHDR_1;
841
} else {
842
return BZ_OK;
843
}
844
}
845
if (s->state >= BZ_X_MAGIC_1) {
846
Int32 r = BZ2_decompress ( s );
847
if (r == BZ_STREAM_END) {
848
if (s->verbosity >= 3)
849
VPrintf2 ( "\n combined CRCs: stored = 0x%08x, computed = 0x%08x",
850
s->storedCombinedCRC, s->calculatedCombinedCRC );
851
if (s->calculatedCombinedCRC != s->storedCombinedCRC)
852
return BZ_DATA_ERROR;
853
return r;
854
}
855
if (s->state != BZ_X_OUTPUT) return r;
856
}
857
}
858
859
AssertH ( 0, 6001 );
860
861
return 0; /*NOTREACHED*/
862
}
863
864
865
/*---------------------------------------------------*/
866
int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm )
867
{
868
DState* s;
869
if (strm == NULL) return BZ_PARAM_ERROR;
870
s = strm->state;
871
if (s == NULL) return BZ_PARAM_ERROR;
872
if (s->strm != strm) return BZ_PARAM_ERROR;
873
874
if (s->tt != NULL) BZFREE(s->tt);
875
if (s->ll16 != NULL) BZFREE(s->ll16);
876
if (s->ll4 != NULL) BZFREE(s->ll4);
877
878
BZFREE(strm->state);
879
strm->state = NULL;
880
881
return BZ_OK;
882
}
883
884
885
#ifndef BZ_NO_STDIO
886
/*---------------------------------------------------*/
887
/*--- File I/O stuff ---*/
888
/*---------------------------------------------------*/
889
890
#define BZ_SETERR(eee) \
891
{ \
892
if (bzerror != NULL) *bzerror = eee; \
893
if (bzf != NULL) bzf->lastErr = eee; \
894
}
895
896
typedef
897
struct {
898
FILE* handle;
899
Char buf[BZ_MAX_UNUSED];
900
Int32 bufN;
901
Bool writing;
902
bz_stream strm;
903
Int32 lastErr;
904
Bool initialisedOk;
905
}
906
bzFile;
907
908
909
/*---------------------------------------------*/
910
static Bool myfeof ( FILE* f )
911
{
912
Int32 c = fgetc ( f );
913
if (c == EOF) return True;
914
ungetc ( c, f );
915
return False;
916
}
917
918
919
/*---------------------------------------------------*/
920
BZFILE* BZ_API(BZ2_bzWriteOpen)
921
( int* bzerror,
922
FILE* f,
923
int blockSize100k,
924
int verbosity,
925
int workFactor )
926
{
927
Int32 ret;
928
bzFile* bzf = NULL;
929
930
BZ_SETERR(BZ_OK);
931
932
if (f == NULL ||
933
(blockSize100k < 1 || blockSize100k > 9) ||
934
(workFactor < 0 || workFactor > 250) ||
935
(verbosity < 0 || verbosity > 4))
936
{ BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
937
938
if (ferror(f))
939
{ BZ_SETERR(BZ_IO_ERROR); return NULL; };
940
941
bzf = malloc ( sizeof(bzFile) );
942
if (bzf == NULL)
943
{ BZ_SETERR(BZ_MEM_ERROR); return NULL; };
944
945
BZ_SETERR(BZ_OK);
946
bzf->initialisedOk = False;
947
bzf->bufN = 0;
948
bzf->handle = f;
949
bzf->writing = True;
950
bzf->strm.bzalloc = NULL;
951
bzf->strm.bzfree = NULL;
952
bzf->strm.opaque = NULL;
953
954
if (workFactor == 0) workFactor = 30;
955
ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
956
verbosity, workFactor );
957
if (ret != BZ_OK)
958
{ BZ_SETERR(ret); free(bzf); return NULL; };
959
960
bzf->strm.avail_in = 0;
961
bzf->initialisedOk = True;
962
return bzf;
963
}
964
965
966
967
/*---------------------------------------------------*/
968
void BZ_API(BZ2_bzWrite)
969
( int* bzerror,
970
BZFILE* b,
971
void* buf,
972
int len )
973
{
974
Int32 n, n2, ret;
975
bzFile* bzf = (bzFile*)b;
976
977
BZ_SETERR(BZ_OK);
978
if (bzf == NULL || buf == NULL || len < 0)
979
{ BZ_SETERR(BZ_PARAM_ERROR); return; };
980
if (!(bzf->writing))
981
{ BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
982
if (ferror(bzf->handle))
983
{ BZ_SETERR(BZ_IO_ERROR); return; };
984
985
if (len == 0)
986
{ BZ_SETERR(BZ_OK); return; };
987
988
bzf->strm.avail_in = len;
989
bzf->strm.next_in = buf;
990
991
while (True) {
992
bzf->strm.avail_out = BZ_MAX_UNUSED;
993
bzf->strm.next_out = bzf->buf;
994
ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
995
if (ret != BZ_RUN_OK)
996
{ BZ_SETERR(ret); return; };
997
998
if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
999
n = BZ_MAX_UNUSED - bzf->strm.avail_out;
1000
n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
1001
n, bzf->handle );
1002
if (n != n2 || ferror(bzf->handle))
1003
{ BZ_SETERR(BZ_IO_ERROR); return; };
1004
}
1005
1006
if (bzf->strm.avail_in == 0)
1007
{ BZ_SETERR(BZ_OK); return; };
1008
}
1009
}
1010
1011
1012
/*---------------------------------------------------*/
1013
void BZ_API(BZ2_bzWriteClose)
1014
( int* bzerror,
1015
BZFILE* b,
1016
int abandon,
1017
unsigned int* nbytes_in,
1018
unsigned int* nbytes_out )
1019
{
1020
BZ2_bzWriteClose64 ( bzerror, b, abandon,
1021
nbytes_in, NULL, nbytes_out, NULL );
1022
}
1023
1024
1025
void BZ_API(BZ2_bzWriteClose64)
1026
( int* bzerror,
1027
BZFILE* b,
1028
int abandon,
1029
unsigned int* nbytes_in_lo32,
1030
unsigned int* nbytes_in_hi32,
1031
unsigned int* nbytes_out_lo32,
1032
unsigned int* nbytes_out_hi32 )
1033
{
1034
Int32 n, n2, ret;
1035
bzFile* bzf = (bzFile*)b;
1036
1037
if (bzf == NULL)
1038
{ BZ_SETERR(BZ_OK); return; };
1039
if (!(bzf->writing))
1040
{ BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
1041
if (ferror(bzf->handle))
1042
{ BZ_SETERR(BZ_IO_ERROR); return; };
1043
1044
if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
1045
if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
1046
if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
1047
if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
1048
1049
if ((!abandon) && bzf->lastErr == BZ_OK) {
1050
while (True) {
1051
bzf->strm.avail_out = BZ_MAX_UNUSED;
1052
bzf->strm.next_out = bzf->buf;
1053
ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
1054
if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
1055
{ BZ_SETERR(ret); return; };
1056
1057
if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
1058
n = BZ_MAX_UNUSED - bzf->strm.avail_out;
1059
n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
1060
n, bzf->handle );
1061
if (n != n2 || ferror(bzf->handle))
1062
{ BZ_SETERR(BZ_IO_ERROR); return; };
1063
}
1064
1065
if (ret == BZ_STREAM_END) break;
1066
}
1067
}
1068
1069
if ( !abandon && !ferror ( bzf->handle ) ) {
1070
fflush ( bzf->handle );
1071
if (ferror(bzf->handle))
1072
{ BZ_SETERR(BZ_IO_ERROR); return; };
1073
}
1074
1075
if (nbytes_in_lo32 != NULL)
1076
*nbytes_in_lo32 = bzf->strm.total_in_lo32;
1077
if (nbytes_in_hi32 != NULL)
1078
*nbytes_in_hi32 = bzf->strm.total_in_hi32;
1079
if (nbytes_out_lo32 != NULL)
1080
*nbytes_out_lo32 = bzf->strm.total_out_lo32;
1081
if (nbytes_out_hi32 != NULL)
1082
*nbytes_out_hi32 = bzf->strm.total_out_hi32;
1083
1084
BZ_SETERR(BZ_OK);
1085
BZ2_bzCompressEnd ( &(bzf->strm) );
1086
free ( bzf );
1087
}
1088
1089
1090
/*---------------------------------------------------*/
1091
BZFILE* BZ_API(BZ2_bzReadOpen)
1092
( int* bzerror,
1093
FILE* f,
1094
int verbosity,
1095
int small,
1096
void* unused,
1097
int nUnused )
1098
{
1099
bzFile* bzf = NULL;
1100
int ret;
1101
1102
BZ_SETERR(BZ_OK);
1103
1104
if (f == NULL ||
1105
(small != 0 && small != 1) ||
1106
(verbosity < 0 || verbosity > 4) ||
1107
(unused == NULL && nUnused != 0) ||
1108
(unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
1109
{ BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
1110
1111
if (ferror(f))
1112
{ BZ_SETERR(BZ_IO_ERROR); return NULL; };
1113
1114
bzf = malloc ( sizeof(bzFile) );
1115
if (bzf == NULL)
1116
{ BZ_SETERR(BZ_MEM_ERROR); return NULL; };
1117
1118
BZ_SETERR(BZ_OK);
1119
1120
bzf->initialisedOk = False;
1121
bzf->handle = f;
1122
bzf->bufN = 0;
1123
bzf->writing = False;
1124
bzf->strm.bzalloc = NULL;
1125
bzf->strm.bzfree = NULL;
1126
bzf->strm.opaque = NULL;
1127
1128
while (nUnused > 0) {
1129
bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
1130
unused = ((void*)( 1 + ((UChar*)(unused)) ));
1131
nUnused--;
1132
}
1133
1134
ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
1135
if (ret != BZ_OK)
1136
{ BZ_SETERR(ret); free(bzf); return NULL; };
1137
1138
bzf->strm.avail_in = bzf->bufN;
1139
bzf->strm.next_in = bzf->buf;
1140
1141
bzf->initialisedOk = True;
1142
return bzf;
1143
}
1144
1145
1146
/*---------------------------------------------------*/
1147
void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
1148
{
1149
bzFile* bzf = (bzFile*)b;
1150
1151
BZ_SETERR(BZ_OK);
1152
if (bzf == NULL)
1153
{ BZ_SETERR(BZ_OK); return; };
1154
1155
if (bzf->writing)
1156
{ BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
1157
1158
if (bzf->initialisedOk)
1159
(void)BZ2_bzDecompressEnd ( &(bzf->strm) );
1160
free ( bzf );
1161
}
1162
1163
1164
/*---------------------------------------------------*/
1165
int BZ_API(BZ2_bzRead)
1166
( int* bzerror,
1167
BZFILE* b,
1168
void* buf,
1169
int len )
1170
{
1171
Int32 n, ret;
1172
bzFile* bzf = (bzFile*)b;
1173
1174
BZ_SETERR(BZ_OK);
1175
1176
if (bzf == NULL || buf == NULL || len < 0)
1177
{ BZ_SETERR(BZ_PARAM_ERROR); return 0; };
1178
1179
if (bzf->writing)
1180
{ BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
1181
1182
if (len == 0)
1183
{ BZ_SETERR(BZ_OK); return 0; };
1184
1185
bzf->strm.avail_out = len;
1186
bzf->strm.next_out = buf;
1187
1188
while (True) {
1189
1190
if (ferror(bzf->handle))
1191
{ BZ_SETERR(BZ_IO_ERROR); return 0; };
1192
1193
if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
1194
n = fread ( bzf->buf, sizeof(UChar),
1195
BZ_MAX_UNUSED, bzf->handle );
1196
if (ferror(bzf->handle))
1197
{ BZ_SETERR(BZ_IO_ERROR); return 0; };
1198
bzf->bufN = n;
1199
bzf->strm.avail_in = bzf->bufN;
1200
bzf->strm.next_in = bzf->buf;
1201
}
1202
1203
ret = BZ2_bzDecompress ( &(bzf->strm) );
1204
1205
if (ret != BZ_OK && ret != BZ_STREAM_END)
1206
{ BZ_SETERR(ret); return 0; };
1207
1208
if (ret == BZ_OK && myfeof(bzf->handle) &&
1209
bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
1210
{ BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
1211
1212
if (ret == BZ_STREAM_END)
1213
{ BZ_SETERR(BZ_STREAM_END);
1214
return len - bzf->strm.avail_out; };
1215
if (bzf->strm.avail_out == 0)
1216
{ BZ_SETERR(BZ_OK); return len; };
1217
1218
}
1219
1220
return 0; /*not reached*/
1221
}
1222
1223
1224
/*---------------------------------------------------*/
1225
void BZ_API(BZ2_bzReadGetUnused)
1226
( int* bzerror,
1227
BZFILE* b,
1228
void** unused,
1229
int* nUnused )
1230
{
1231
bzFile* bzf = (bzFile*)b;
1232
if (bzf == NULL)
1233
{ BZ_SETERR(BZ_PARAM_ERROR); return; };
1234
if (bzf->lastErr != BZ_STREAM_END)
1235
{ BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
1236
if (unused == NULL || nUnused == NULL)
1237
{ BZ_SETERR(BZ_PARAM_ERROR); return; };
1238
1239
BZ_SETERR(BZ_OK);
1240
*nUnused = bzf->strm.avail_in;
1241
*unused = bzf->strm.next_in;
1242
}
1243
#endif
1244
1245
1246
/*---------------------------------------------------*/
1247
/*--- Misc convenience stuff ---*/
1248
/*---------------------------------------------------*/
1249
1250
/*---------------------------------------------------*/
1251
int BZ_API(BZ2_bzBuffToBuffCompress)
1252
( char* dest,
1253
unsigned int* destLen,
1254
char* source,
1255
unsigned int sourceLen,
1256
int blockSize100k,
1257
int verbosity,
1258
int workFactor )
1259
{
1260
bz_stream strm;
1261
int ret;
1262
1263
if (dest == NULL || destLen == NULL ||
1264
source == NULL ||
1265
blockSize100k < 1 || blockSize100k > 9 ||
1266
verbosity < 0 || verbosity > 4 ||
1267
workFactor < 0 || workFactor > 250)
1268
return BZ_PARAM_ERROR;
1269
1270
if (workFactor == 0) workFactor = 30;
1271
strm.bzalloc = NULL;
1272
strm.bzfree = NULL;
1273
strm.opaque = NULL;
1274
ret = BZ2_bzCompressInit ( &strm, blockSize100k,
1275
verbosity, workFactor );
1276
if (ret != BZ_OK) return ret;
1277
1278
strm.next_in = source;
1279
strm.next_out = dest;
1280
strm.avail_in = sourceLen;
1281
strm.avail_out = *destLen;
1282
1283
ret = BZ2_bzCompress ( &strm, BZ_FINISH );
1284
if (ret == BZ_FINISH_OK) goto output_overflow;
1285
if (ret != BZ_STREAM_END) goto errhandler;
1286
1287
/* normal termination */
1288
*destLen -= strm.avail_out;
1289
BZ2_bzCompressEnd ( &strm );
1290
return BZ_OK;
1291
1292
output_overflow:
1293
BZ2_bzCompressEnd ( &strm );
1294
return BZ_OUTBUFF_FULL;
1295
1296
errhandler:
1297
BZ2_bzCompressEnd ( &strm );
1298
return ret;
1299
}
1300
1301
1302
/*---------------------------------------------------*/
1303
int BZ_API(BZ2_bzBuffToBuffDecompress)
1304
( char* dest,
1305
unsigned int* destLen,
1306
char* source,
1307
unsigned int sourceLen,
1308
int small,
1309
int verbosity )
1310
{
1311
bz_stream strm;
1312
int ret;
1313
1314
if (dest == NULL || destLen == NULL ||
1315
source == NULL ||
1316
(small != 0 && small != 1) ||
1317
verbosity < 0 || verbosity > 4)
1318
return BZ_PARAM_ERROR;
1319
1320
strm.bzalloc = NULL;
1321
strm.bzfree = NULL;
1322
strm.opaque = NULL;
1323
ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
1324
if (ret != BZ_OK) return ret;
1325
1326
strm.next_in = source;
1327
strm.next_out = dest;
1328
strm.avail_in = sourceLen;
1329
strm.avail_out = *destLen;
1330
1331
ret = BZ2_bzDecompress ( &strm );
1332
if (ret == BZ_OK) goto output_overflow_or_eof;
1333
if (ret != BZ_STREAM_END) goto errhandler;
1334
1335
/* normal termination */
1336
*destLen -= strm.avail_out;
1337
BZ2_bzDecompressEnd ( &strm );
1338
return BZ_OK;
1339
1340
output_overflow_or_eof:
1341
if (strm.avail_out > 0) {
1342
BZ2_bzDecompressEnd ( &strm );
1343
return BZ_UNEXPECTED_EOF;
1344
} else {
1345
BZ2_bzDecompressEnd ( &strm );
1346
return BZ_OUTBUFF_FULL;
1347
};
1348
1349
errhandler:
1350
BZ2_bzDecompressEnd ( &strm );
1351
return ret;
1352
}
1353
1354
1355
/*---------------------------------------------------*/
1356
/*--
1357
Code contributed by Yoshioka Tsuneo ([email protected])
1358
to support better zlib compatibility.
1359
This code is not _officially_ part of libbzip2 (yet);
1360
I haven't tested it, documented it, or considered the
1361
threading-safeness of it.
1362
If this code breaks, please contact both Yoshioka and me.
1363
--*/
1364
/*---------------------------------------------------*/
1365
1366
/*---------------------------------------------------*/
1367
/*--
1368
return version like "0.9.5d, 4-Sept-1999".
1369
--*/
1370
const char * BZ_API(BZ2_bzlibVersion)(void)
1371
{
1372
return BZ_VERSION;
1373
}
1374
1375
1376
#ifndef BZ_NO_STDIO
1377
/*---------------------------------------------------*/
1378
1379
#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
1380
# include <fcntl.h>
1381
# include <io.h>
1382
# define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
1383
#else
1384
# define SET_BINARY_MODE(file)
1385
#endif
1386
static
1387
BZFILE * bzopen_or_bzdopen
1388
( const char *path, /* no use when bzdopen */
1389
int fd, /* no use when bzdopen */
1390
const char *mode,
1391
int open_mode) /* bzopen: 0, bzdopen:1 */
1392
{
1393
int bzerr;
1394
char unused[BZ_MAX_UNUSED];
1395
int blockSize100k = 9;
1396
int writing = 0;
1397
char mode2[10] = "";
1398
FILE *fp = NULL;
1399
BZFILE *bzfp = NULL;
1400
int verbosity = 0;
1401
int workFactor = 30;
1402
int smallMode = 0;
1403
int nUnused = 0;
1404
1405
if (mode == NULL) return NULL;
1406
while (*mode) {
1407
switch (*mode) {
1408
case 'r':
1409
writing = 0; break;
1410
case 'w':
1411
writing = 1; break;
1412
case 's':
1413
smallMode = 1; break;
1414
default:
1415
if (isdigit((int)(*mode))) {
1416
blockSize100k = *mode-BZ_HDR_0;
1417
}
1418
}
1419
mode++;
1420
}
1421
strcat(mode2, writing ? "w" : "r" );
1422
strcat(mode2,"b"); /* binary mode */
1423
1424
if (open_mode==0) {
1425
if (path==NULL || strcmp(path,"")==0) {
1426
fp = (writing ? stdout : stdin);
1427
SET_BINARY_MODE(fp);
1428
} else {
1429
fp = fopen(path,mode2);
1430
}
1431
} else {
1432
#ifdef BZ_STRICT_ANSI
1433
fp = NULL;
1434
#else
1435
fp = fdopen(fd,mode2);
1436
#endif
1437
}
1438
if (fp == NULL) return NULL;
1439
1440
if (writing) {
1441
/* Guard against total chaos and anarchy -- JRS */
1442
if (blockSize100k < 1) blockSize100k = 1;
1443
if (blockSize100k > 9) blockSize100k = 9;
1444
bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
1445
verbosity,workFactor);
1446
} else {
1447
bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
1448
unused,nUnused);
1449
}
1450
if (bzfp == NULL) {
1451
if (fp != stdin && fp != stdout) fclose(fp);
1452
return NULL;
1453
}
1454
return bzfp;
1455
}
1456
1457
1458
/*---------------------------------------------------*/
1459
/*--
1460
open file for read or write.
1461
ex) bzopen("file","w9")
1462
case path="" or NULL => use stdin or stdout.
1463
--*/
1464
BZFILE * BZ_API(BZ2_bzopen)
1465
( const char *path,
1466
const char *mode )
1467
{
1468
return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
1469
}
1470
1471
1472
/*---------------------------------------------------*/
1473
BZFILE * BZ_API(BZ2_bzdopen)
1474
( int fd,
1475
const char *mode )
1476
{
1477
return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
1478
}
1479
1480
1481
/*---------------------------------------------------*/
1482
int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
1483
{
1484
int bzerr, nread;
1485
if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
1486
nread = BZ2_bzRead(&bzerr,b,buf,len);
1487
if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
1488
return nread;
1489
} else {
1490
return -1;
1491
}
1492
}
1493
1494
1495
/*---------------------------------------------------*/
1496
int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
1497
{
1498
int bzerr;
1499
1500
BZ2_bzWrite(&bzerr,b,buf,len);
1501
if(bzerr == BZ_OK){
1502
return len;
1503
}else{
1504
return -1;
1505
}
1506
}
1507
1508
1509
/*---------------------------------------------------*/
1510
int BZ_API(BZ2_bzflush) (BZFILE *b)
1511
{
1512
/* do nothing now... */
1513
return 0;
1514
}
1515
1516
1517
/*---------------------------------------------------*/
1518
void BZ_API(BZ2_bzclose) (BZFILE* b)
1519
{
1520
int bzerr;
1521
FILE *fp;
1522
1523
if (b==NULL) {return;}
1524
fp = ((bzFile *)b)->handle;
1525
if(((bzFile*)b)->writing){
1526
BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
1527
if(bzerr != BZ_OK){
1528
BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
1529
}
1530
}else{
1531
BZ2_bzReadClose(&bzerr,b);
1532
}
1533
if(fp!=stdin && fp!=stdout){
1534
fclose(fp);
1535
}
1536
}
1537
1538
1539
/*---------------------------------------------------*/
1540
/*--
1541
return last error code
1542
--*/
1543
static const char *bzerrorstrings[] = {
1544
"OK"
1545
,"SEQUENCE_ERROR"
1546
,"PARAM_ERROR"
1547
,"MEM_ERROR"
1548
,"DATA_ERROR"
1549
,"DATA_ERROR_MAGIC"
1550
,"IO_ERROR"
1551
,"UNEXPECTED_EOF"
1552
,"OUTBUFF_FULL"
1553
,"CONFIG_ERROR"
1554
,"???" /* for future */
1555
,"???" /* for future */
1556
,"???" /* for future */
1557
,"???" /* for future */
1558
,"???" /* for future */
1559
,"???" /* for future */
1560
};
1561
1562
1563
const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
1564
{
1565
int err = ((bzFile *)b)->lastErr;
1566
1567
if(err>0) err = 0;
1568
*errnum = err;
1569
return bzerrorstrings[err*-1];
1570
}
1571
#endif
1572
1573
1574
/*-------------------------------------------------------------*/
1575
/*--- end bzlib.c ---*/
1576
/*-------------------------------------------------------------*/
1577
1578