modules/libbz2/src/bzlib.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial