annotate src/bzip2-1.0.6/bzlib.c @ 83:ae30d91d2ffe

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