annotate src/bzip2-1.0.6/bzlib.c @ 169:223a55898ab9 tip default

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