mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-10-25 01:58:13 +01:00 
			
		
		
		
	This allows the caller to easily detect how much of the destination buffer has been used. Signed-off-by: Simon Glass <sjg@chromium.org>
		
			
				
	
	
		
			1602 lines
		
	
	
		
			43 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1602 lines
		
	
	
		
			43 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include <config.h>
 | |
| #include <common.h>
 | |
| #include <watchdog.h>
 | |
| 
 | |
| /*
 | |
|  * This file is a modified version of bzlib.c from the bzip2-1.0.2
 | |
|  * distribution which can be found at http://sources.redhat.com/bzip2/
 | |
|  */
 | |
| 
 | |
| /*-------------------------------------------------------------*/
 | |
| /*--- Library top-level functions.                          ---*/
 | |
| /*---                                               bzlib.c ---*/
 | |
| /*-------------------------------------------------------------*/
 | |
| 
 | |
| /*--
 | |
|   This file is a part of bzip2 and/or libbzip2, a program and
 | |
|   library for lossless, block-sorting data compression.
 | |
| 
 | |
|   Copyright (C) 1996-2002 Julian R Seward.  All rights reserved.
 | |
| 
 | |
|   Redistribution and use in source and binary forms, with or without
 | |
|   modification, are permitted provided that the following conditions
 | |
|   are met:
 | |
| 
 | |
|   1. Redistributions of source code must retain the above copyright
 | |
|      notice, this list of conditions and the following disclaimer.
 | |
| 
 | |
|   2. The origin of this software must not be misrepresented; you must
 | |
|      not claim that you wrote the original software.  If you use this
 | |
|      software in a product, an acknowledgment in the product
 | |
|      documentation would be appreciated but is not required.
 | |
| 
 | |
|   3. Altered source versions must be plainly marked as such, and must
 | |
|      not be misrepresented as being the original software.
 | |
| 
 | |
|   4. The name of the author may not be used to endorse or promote
 | |
|      products derived from this software without specific prior written
 | |
|      permission.
 | |
| 
 | |
|   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 | |
|   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | |
|   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | |
|   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 | |
|   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | |
|   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 | |
|   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | |
|   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 | |
|   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | |
|   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | |
|   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| 
 | |
|   Julian Seward, Cambridge, UK.
 | |
|   jseward@acm.org
 | |
|   bzip2/libbzip2 version 1.0 of 21 March 2000
 | |
| 
 | |
|   This program is based on (at least) the work of:
 | |
|      Mike Burrows
 | |
|      David Wheeler
 | |
|      Peter Fenwick
 | |
|      Alistair Moffat
 | |
|      Radford Neal
 | |
|      Ian H. Witten
 | |
|      Robert Sedgewick
 | |
|      Jon L. Bentley
 | |
| 
 | |
|   For more information on these sources, see the manual.
 | |
| --*/
 | |
| 
 | |
| /*--
 | |
|    CHANGES
 | |
|    ~~~~~~~
 | |
|    0.9.0 -- original version.
 | |
| 
 | |
|    0.9.0a/b -- no changes in this file.
 | |
| 
 | |
|    0.9.0c
 | |
|       * made zero-length BZ_FLUSH work correctly in bzCompress().
 | |
|       * fixed bzWrite/bzRead to ignore zero-length requests.
 | |
|       * fixed bzread to correctly handle read requests after EOF.
 | |
|       * wrong parameter order in call to bzDecompressInit in
 | |
| 	bzBuffToBuffDecompress.  Fixed.
 | |
| --*/
 | |
| 
 | |
| #include "bzlib_private.h"
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| /*--- Compression stuff                           ---*/
 | |
| /*---------------------------------------------------*/
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| #ifndef BZ_NO_STDIO
 | |
| void BZ2_bz__AssertH__fail ( int errcode )
 | |
| {
 | |
|    fprintf(stderr,
 | |
|       "\n\nbzip2/libbzip2: internal error number %d.\n"
 | |
|       "This is a bug in bzip2/libbzip2, %s.\n"
 | |
|       "Please report it to me at: jseward@acm.org.  If this happened\n"
 | |
|       "when you were using some program which uses libbzip2 as a\n"
 | |
|       "component, you should also report this bug to the author(s)\n"
 | |
|       "of that program.  Please make an effort to report this bug;\n"
 | |
|       "timely and accurate bug reports eventually lead to higher\n"
 | |
|       "quality software.  Thanks.  Julian Seward, 30 December 2001.\n\n",
 | |
|       errcode,
 | |
|       BZ2_bzlibVersion()
 | |
|    );
 | |
| 
 | |
|    if (errcode == 1007) {
 | |
|    fprintf(stderr,
 | |
|       "\n*** A special note about internal error number 1007 ***\n"
 | |
|       "\n"
 | |
|       "Experience suggests that a common cause of i.e. 1007\n"
 | |
|       "is unreliable memory or other hardware.  The 1007 assertion\n"
 | |
|       "just happens to cross-check the results of huge numbers of\n"
 | |
|       "memory reads/writes, and so acts (unintendedly) as a stress\n"
 | |
|       "test of your memory system.\n"
 | |
|       "\n"
 | |
|       "I suggest the following: try compressing the file again,\n"
 | |
|       "possibly monitoring progress in detail with the -vv flag.\n"
 | |
|       "\n"
 | |
|       "* If the error cannot be reproduced, and/or happens at different\n"
 | |
|       "  points in compression, you may have a flaky memory system.\n"
 | |
|       "  Try a memory-test program.  I have used Memtest86\n"
 | |
|       "  (www.memtest86.com).  At the time of writing it is free (GPLd).\n"
 | |
|       "  Memtest86 tests memory much more thorougly than your BIOSs\n"
 | |
|       "  power-on test, and may find failures that the BIOS doesn't.\n"
 | |
|       "\n"
 | |
|       "* If the error can be repeatably reproduced, this is a bug in\n"
 | |
|       "  bzip2, and I would very much like to hear about it.  Please\n"
 | |
|       "  let me know, and, ideally, save a copy of the file causing the\n"
 | |
|       "  problem -- without which I will be unable to investigate it.\n"
 | |
|       "\n"
 | |
|    );
 | |
|    }
 | |
| 
 | |
|    exit(3);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| static
 | |
| int bz_config_ok ( void )
 | |
| {
 | |
|    if (sizeof(int)   != 4) return 0;
 | |
|    if (sizeof(short) != 2) return 0;
 | |
|    if (sizeof(char)  != 1) return 0;
 | |
|    return 1;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| static
 | |
| void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
 | |
| {
 | |
|    void* v = malloc ( items * size );
 | |
|    return v;
 | |
| }
 | |
| 
 | |
| static
 | |
| void default_bzfree ( void* opaque, void* addr )
 | |
| {
 | |
|    if (addr != NULL) free ( addr );
 | |
| }
 | |
| 
 | |
| #ifndef BZ_NO_COMPRESS
 | |
| /*---------------------------------------------------*/
 | |
| static
 | |
| void prepare_new_block ( EState* s )
 | |
| {
 | |
|    Int32 i;
 | |
|    s->nblock = 0;
 | |
|    s->numZ = 0;
 | |
|    s->state_out_pos = 0;
 | |
|    BZ_INITIALISE_CRC ( s->blockCRC );
 | |
|    for (i = 0; i < 256; i++) s->inUse[i] = False;
 | |
|    s->blockNo++;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| static
 | |
| void init_RL ( EState* s )
 | |
| {
 | |
|    s->state_in_ch  = 256;
 | |
|    s->state_in_len = 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| static
 | |
| Bool isempty_RL ( EState* s )
 | |
| {
 | |
|    if (s->state_in_ch < 256 && s->state_in_len > 0)
 | |
|       return False; else
 | |
|       return True;
 | |
| }
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| int BZ_API(BZ2_bzCompressInit)
 | |
| 		    ( bz_stream* strm,
 | |
| 		     int        blockSize100k,
 | |
| 		     int        verbosity,
 | |
| 		     int        workFactor )
 | |
| {
 | |
|    Int32   n;
 | |
|    EState* s;
 | |
| 
 | |
|    if (!bz_config_ok()) return BZ_CONFIG_ERROR;
 | |
| 
 | |
|    if (strm == NULL ||
 | |
|        blockSize100k < 1 || blockSize100k > 9 ||
 | |
|        workFactor < 0 || workFactor > 250)
 | |
|      return BZ_PARAM_ERROR;
 | |
| 
 | |
|    if (workFactor == 0) workFactor = 30;
 | |
|    if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
 | |
|    if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
 | |
| 
 | |
|    s = BZALLOC( sizeof(EState) );
 | |
|    if (s == NULL) return BZ_MEM_ERROR;
 | |
|    s->strm = strm;
 | |
| 
 | |
|    s->arr1 = NULL;
 | |
|    s->arr2 = NULL;
 | |
|    s->ftab = NULL;
 | |
| 
 | |
|    n       = 100000 * blockSize100k;
 | |
|    s->arr1 = BZALLOC( n                  * sizeof(UInt32) );
 | |
|    s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
 | |
|    s->ftab = BZALLOC( 65537              * sizeof(UInt32) );
 | |
| 
 | |
|    if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
 | |
|       if (s->arr1 != NULL) BZFREE(s->arr1);
 | |
|       if (s->arr2 != NULL) BZFREE(s->arr2);
 | |
|       if (s->ftab != NULL) BZFREE(s->ftab);
 | |
|       if (s       != NULL) BZFREE(s);
 | |
|       return BZ_MEM_ERROR;
 | |
|    }
 | |
| 
 | |
|    s->blockNo           = 0;
 | |
|    s->state             = BZ_S_INPUT;
 | |
|    s->mode              = BZ_M_RUNNING;
 | |
|    s->combinedCRC       = 0;
 | |
|    s->blockSize100k     = blockSize100k;
 | |
|    s->nblockMAX         = 100000 * blockSize100k - 19;
 | |
|    s->verbosity         = verbosity;
 | |
|    s->workFactor        = workFactor;
 | |
| 
 | |
|    s->block             = (UChar*)s->arr2;
 | |
|    s->mtfv              = (UInt16*)s->arr1;
 | |
|    s->zbits             = NULL;
 | |
|    s->ptr               = (UInt32*)s->arr1;
 | |
| 
 | |
|    strm->state          = s;
 | |
|    strm->total_in_lo32  = 0;
 | |
|    strm->total_in_hi32  = 0;
 | |
|    strm->total_out_lo32 = 0;
 | |
|    strm->total_out_hi32 = 0;
 | |
|    init_RL ( s );
 | |
|    prepare_new_block ( s );
 | |
|    return BZ_OK;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| static
 | |
| void add_pair_to_block ( EState* s )
 | |
| {
 | |
|    Int32 i;
 | |
|    UChar ch = (UChar)(s->state_in_ch);
 | |
|    for (i = 0; i < s->state_in_len; i++) {
 | |
|       BZ_UPDATE_CRC( s->blockCRC, ch );
 | |
|    }
 | |
|    s->inUse[s->state_in_ch] = True;
 | |
|    switch (s->state_in_len) {
 | |
|       case 1:
 | |
| 	 s->block[s->nblock] = (UChar)ch; s->nblock++;
 | |
| 	 break;
 | |
|       case 2:
 | |
| 	 s->block[s->nblock] = (UChar)ch; s->nblock++;
 | |
| 	 s->block[s->nblock] = (UChar)ch; s->nblock++;
 | |
| 	 break;
 | |
|       case 3:
 | |
| 	 s->block[s->nblock] = (UChar)ch; s->nblock++;
 | |
| 	 s->block[s->nblock] = (UChar)ch; s->nblock++;
 | |
| 	 s->block[s->nblock] = (UChar)ch; s->nblock++;
 | |
| 	 break;
 | |
|       default:
 | |
| 	 s->inUse[s->state_in_len-4] = True;
 | |
| 	 s->block[s->nblock] = (UChar)ch; s->nblock++;
 | |
| 	 s->block[s->nblock] = (UChar)ch; s->nblock++;
 | |
| 	 s->block[s->nblock] = (UChar)ch; s->nblock++;
 | |
| 	 s->block[s->nblock] = (UChar)ch; s->nblock++;
 | |
| 	 s->block[s->nblock] = ((UChar)(s->state_in_len-4));
 | |
| 	 s->nblock++;
 | |
| 	 break;
 | |
|    }
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| static
 | |
| void flush_RL ( EState* s )
 | |
| {
 | |
|    if (s->state_in_ch < 256) add_pair_to_block ( s );
 | |
|    init_RL ( s );
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| #define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
 | |
| {                                                 \
 | |
|    UInt32 zchh = (UInt32)(zchh0);                 \
 | |
|    /*-- fast track the common case --*/           \
 | |
|    if (zchh != zs->state_in_ch &&                 \
 | |
|        zs->state_in_len == 1) {                   \
 | |
|       UChar ch = (UChar)(zs->state_in_ch);        \
 | |
|       BZ_UPDATE_CRC( zs->blockCRC, ch );          \
 | |
|       zs->inUse[zs->state_in_ch] = True;          \
 | |
|       zs->block[zs->nblock] = (UChar)ch;          \
 | |
|       zs->nblock++;                               \
 | |
|       zs->state_in_ch = zchh;                     \
 | |
|    }                                              \
 | |
|    else                                           \
 | |
|    /*-- general, uncommon cases --*/              \
 | |
|    if (zchh != zs->state_in_ch ||                 \
 | |
|       zs->state_in_len == 255) {                  \
 | |
|       if (zs->state_in_ch < 256)                  \
 | |
| 	 add_pair_to_block ( zs );                \
 | |
|       zs->state_in_ch = zchh;                     \
 | |
|       zs->state_in_len = 1;                       \
 | |
|    } else {                                       \
 | |
|       zs->state_in_len++;                         \
 | |
|    }                                              \
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| static
 | |
| Bool copy_input_until_stop ( EState* s )
 | |
| {
 | |
|    Bool progress_in = False;
 | |
| 
 | |
|    if (s->mode == BZ_M_RUNNING) {
 | |
| 
 | |
|       /*-- fast track the common case --*/
 | |
|       while (True) {
 | |
| 	 /*-- block full? --*/
 | |
| 	 if (s->nblock >= s->nblockMAX) break;
 | |
| 	 /*-- no input? --*/
 | |
| 	 if (s->strm->avail_in == 0) break;
 | |
| 	 progress_in = True;
 | |
| 	 ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
 | |
| 	 s->strm->next_in++;
 | |
| 	 s->strm->avail_in--;
 | |
| 	 s->strm->total_in_lo32++;
 | |
| 	 if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
 | |
|       }
 | |
| 
 | |
|    } else {
 | |
| 
 | |
|       /*-- general, uncommon case --*/
 | |
|       while (True) {
 | |
| 	 /*-- block full? --*/
 | |
| 	 if (s->nblock >= s->nblockMAX) break;
 | |
| 	 /*-- no input? --*/
 | |
| 	 if (s->strm->avail_in == 0) break;
 | |
| 	 /*-- flush/finish end? --*/
 | |
| 	 if (s->avail_in_expect == 0) break;
 | |
| 	 progress_in = True;
 | |
| 	 ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
 | |
| 	 s->strm->next_in++;
 | |
| 	 s->strm->avail_in--;
 | |
| 	 s->strm->total_in_lo32++;
 | |
| 	 if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
 | |
| 	 s->avail_in_expect--;
 | |
|       }
 | |
|    }
 | |
|    return progress_in;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| static
 | |
| Bool copy_output_until_stop ( EState* s )
 | |
| {
 | |
|    Bool progress_out = False;
 | |
| 
 | |
|    while (True) {
 | |
| 
 | |
|       /*-- no output space? --*/
 | |
|       if (s->strm->avail_out == 0) break;
 | |
| 
 | |
|       /*-- block done? --*/
 | |
|       if (s->state_out_pos >= s->numZ) break;
 | |
| 
 | |
|       progress_out = True;
 | |
|       *(s->strm->next_out) = s->zbits[s->state_out_pos];
 | |
|       s->state_out_pos++;
 | |
|       s->strm->avail_out--;
 | |
|       s->strm->next_out++;
 | |
|       s->strm->total_out_lo32++;
 | |
|       if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
 | |
|    }
 | |
| 
 | |
|    return progress_out;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| static
 | |
| Bool handle_compress ( bz_stream* strm )
 | |
| {
 | |
|    Bool progress_in  = False;
 | |
|    Bool progress_out = False;
 | |
|    EState* s = strm->state;
 | |
| 
 | |
|    while (True) {
 | |
| 
 | |
|       if (s->state == BZ_S_OUTPUT) {
 | |
| 	 progress_out |= copy_output_until_stop ( s );
 | |
| 	 if (s->state_out_pos < s->numZ) break;
 | |
| 	 if (s->mode == BZ_M_FINISHING &&
 | |
| 	     s->avail_in_expect == 0 &&
 | |
| 	     isempty_RL(s)) break;
 | |
| 	 prepare_new_block ( s );
 | |
| 	 s->state = BZ_S_INPUT;
 | |
| 	 if (s->mode == BZ_M_FLUSHING &&
 | |
| 	     s->avail_in_expect == 0 &&
 | |
| 	     isempty_RL(s)) break;
 | |
|       }
 | |
| 
 | |
|       if (s->state == BZ_S_INPUT) {
 | |
| 	 progress_in |= copy_input_until_stop ( s );
 | |
| 	 if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
 | |
| 	    flush_RL ( s );
 | |
| 	    BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
 | |
| 	    s->state = BZ_S_OUTPUT;
 | |
| 	 }
 | |
| 	 else
 | |
| 	 if (s->nblock >= s->nblockMAX) {
 | |
| 	    BZ2_compressBlock ( s, False );
 | |
| 	    s->state = BZ_S_OUTPUT;
 | |
| 	 }
 | |
| 	 else
 | |
| 	 if (s->strm->avail_in == 0) {
 | |
| 	    break;
 | |
| 	 }
 | |
|       }
 | |
| 
 | |
|    }
 | |
| 
 | |
|    return progress_in || progress_out;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
 | |
| {
 | |
|    Bool progress;
 | |
|    EState* s;
 | |
|    if (strm == NULL) return BZ_PARAM_ERROR;
 | |
|    s = strm->state;
 | |
|    if (s == NULL) return BZ_PARAM_ERROR;
 | |
|    if (s->strm != strm) return BZ_PARAM_ERROR;
 | |
| 
 | |
|    preswitch:
 | |
|    switch (s->mode) {
 | |
| 
 | |
|       case BZ_M_IDLE:
 | |
| 	 return BZ_SEQUENCE_ERROR;
 | |
| 
 | |
|       case BZ_M_RUNNING:
 | |
| 	 if (action == BZ_RUN) {
 | |
| 	    progress = handle_compress ( strm );
 | |
| 	    return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
 | |
| 	 }
 | |
| 	 else
 | |
| 	 if (action == BZ_FLUSH) {
 | |
| 	    s->avail_in_expect = strm->avail_in;
 | |
| 	    s->mode = BZ_M_FLUSHING;
 | |
| 	    goto preswitch;
 | |
| 	 }
 | |
| 	 else
 | |
| 	 if (action == BZ_FINISH) {
 | |
| 	    s->avail_in_expect = strm->avail_in;
 | |
| 	    s->mode = BZ_M_FINISHING;
 | |
| 	    goto preswitch;
 | |
| 	 }
 | |
| 	 else
 | |
| 	    return BZ_PARAM_ERROR;
 | |
| 
 | |
|       case BZ_M_FLUSHING:
 | |
| 	 if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
 | |
| 	 if (s->avail_in_expect != s->strm->avail_in)
 | |
| 	    return BZ_SEQUENCE_ERROR;
 | |
| 	 progress = handle_compress ( strm );
 | |
| 	 if (s->avail_in_expect > 0 || !isempty_RL(s) ||
 | |
| 	     s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
 | |
| 	 s->mode = BZ_M_RUNNING;
 | |
| 	 return BZ_RUN_OK;
 | |
| 
 | |
|       case BZ_M_FINISHING:
 | |
| 	 if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
 | |
| 	 if (s->avail_in_expect != s->strm->avail_in)
 | |
| 	    return BZ_SEQUENCE_ERROR;
 | |
| 	 progress = handle_compress ( strm );
 | |
| 	 if (!progress) return BZ_SEQUENCE_ERROR;
 | |
| 	 if (s->avail_in_expect > 0 || !isempty_RL(s) ||
 | |
| 	     s->state_out_pos < s->numZ) return BZ_FINISH_OK;
 | |
| 	 s->mode = BZ_M_IDLE;
 | |
| 	 return BZ_STREAM_END;
 | |
|    }
 | |
|    return BZ_OK; /*--not reached--*/
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| int BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
 | |
| {
 | |
|    EState* s;
 | |
|    if (strm == NULL) return BZ_PARAM_ERROR;
 | |
|    s = strm->state;
 | |
|    if (s == NULL) return BZ_PARAM_ERROR;
 | |
|    if (s->strm != strm) return BZ_PARAM_ERROR;
 | |
| 
 | |
|    if (s->arr1 != NULL) BZFREE(s->arr1);
 | |
|    if (s->arr2 != NULL) BZFREE(s->arr2);
 | |
|    if (s->ftab != NULL) BZFREE(s->ftab);
 | |
|    BZFREE(strm->state);
 | |
| 
 | |
|    strm->state = NULL;
 | |
| 
 | |
|    return BZ_OK;
 | |
| }
 | |
| #endif /* BZ_NO_COMPRESS */
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| /*--- Decompression stuff                         ---*/
 | |
| /*---------------------------------------------------*/
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| int BZ_API(BZ2_bzDecompressInit)
 | |
| 		     ( bz_stream* strm,
 | |
| 		       int        verbosity,
 | |
| 		       int        small )
 | |
| {
 | |
|    DState* s;
 | |
| 
 | |
|    if (!bz_config_ok()) return BZ_CONFIG_ERROR;
 | |
| 
 | |
|    if (strm == NULL) return BZ_PARAM_ERROR;
 | |
|    if (small != 0 && small != 1) return BZ_PARAM_ERROR;
 | |
|    if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
 | |
| 
 | |
|    if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
 | |
|    if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
 | |
| 
 | |
|    s = BZALLOC( sizeof(DState) );
 | |
|    if (s == NULL) return BZ_MEM_ERROR;
 | |
|    s->strm                  = strm;
 | |
|    strm->state              = s;
 | |
|    s->state                 = BZ_X_MAGIC_1;
 | |
|    s->bsLive                = 0;
 | |
|    s->bsBuff                = 0;
 | |
|    s->calculatedCombinedCRC = 0;
 | |
|    strm->total_in_lo32      = 0;
 | |
|    strm->total_in_hi32      = 0;
 | |
|    strm->total_out_lo32     = 0;
 | |
|    strm->total_out_hi32     = 0;
 | |
|    s->smallDecompress       = (Bool)small;
 | |
|    s->ll4                   = NULL;
 | |
|    s->ll16                  = NULL;
 | |
|    s->tt                    = NULL;
 | |
|    s->currBlockNo           = 0;
 | |
|    s->verbosity             = verbosity;
 | |
| 
 | |
|    return BZ_OK;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| static
 | |
| void unRLE_obuf_to_output_FAST ( DState* s )
 | |
| {
 | |
|    UChar k1;
 | |
| 
 | |
|    if (s->blockRandomised) {
 | |
| 
 | |
|       while (True) {
 | |
| 	 /* try to finish existing run */
 | |
| 	 while (True) {
 | |
| 	    if (s->strm->avail_out == 0) return;
 | |
| 	    if (s->state_out_len == 0) break;
 | |
| 	    *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
 | |
| 	    BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
 | |
| 	    s->state_out_len--;
 | |
| 	    s->strm->next_out++;
 | |
| 	    s->strm->avail_out--;
 | |
| 	    s->strm->total_out_lo32++;
 | |
| 	    if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
 | |
| 	 }
 | |
| 
 | |
| 	 /* can a new run be started? */
 | |
| 	 if (s->nblock_used == s->save_nblock+1) return;
 | |
| 
 | |
| 
 | |
| 	 s->state_out_len = 1;
 | |
| 	 s->state_out_ch = s->k0;
 | |
| 	 BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
 | |
| 	 k1 ^= BZ_RAND_MASK; s->nblock_used++;
 | |
| 	 if (s->nblock_used == s->save_nblock+1) continue;
 | |
| 	 if (k1 != s->k0) { s->k0 = k1; continue; };
 | |
| 
 | |
| 	 s->state_out_len = 2;
 | |
| 	 BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
 | |
| 	 k1 ^= BZ_RAND_MASK; s->nblock_used++;
 | |
| 	 if (s->nblock_used == s->save_nblock+1) continue;
 | |
| 	 if (k1 != s->k0) { s->k0 = k1; continue; };
 | |
| 
 | |
| 	 s->state_out_len = 3;
 | |
| 	 BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
 | |
| 	 k1 ^= BZ_RAND_MASK; s->nblock_used++;
 | |
| 	 if (s->nblock_used == s->save_nblock+1) continue;
 | |
| 	 if (k1 != s->k0) { s->k0 = k1; continue; };
 | |
| 
 | |
| 	 BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
 | |
| 	 k1 ^= BZ_RAND_MASK; s->nblock_used++;
 | |
| 	 s->state_out_len = ((Int32)k1) + 4;
 | |
| 	 BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
 | |
| 	 s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
 | |
|       }
 | |
| 
 | |
|    } else {
 | |
| 
 | |
|       /* restore */
 | |
|       UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
 | |
|       UChar         c_state_out_ch       = s->state_out_ch;
 | |
|       Int32         c_state_out_len      = s->state_out_len;
 | |
|       Int32         c_nblock_used        = s->nblock_used;
 | |
|       Int32         c_k0                 = s->k0;
 | |
|       UInt32*       c_tt                 = s->tt;
 | |
|       UInt32        c_tPos               = s->tPos;
 | |
|       char*         cs_next_out          = s->strm->next_out;
 | |
|       unsigned int  cs_avail_out         = s->strm->avail_out;
 | |
|       /* end restore */
 | |
| 
 | |
|       UInt32       avail_out_INIT = cs_avail_out;
 | |
|       Int32        s_save_nblockPP = s->save_nblock+1;
 | |
|       unsigned int total_out_lo32_old;
 | |
| 
 | |
|       while (True) {
 | |
| 
 | |
| 	 /* try to finish existing run */
 | |
| 	 if (c_state_out_len > 0) {
 | |
| 	    while (True) {
 | |
| 	       if (cs_avail_out == 0) goto return_notr;
 | |
| 	       if (c_state_out_len == 1) break;
 | |
| 	       *( (UChar*)(cs_next_out) ) = c_state_out_ch;
 | |
| 	       BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
 | |
| 	       c_state_out_len--;
 | |
| 	       cs_next_out++;
 | |
| 	       cs_avail_out--;
 | |
| 	    }
 | |
| 	    s_state_out_len_eq_one:
 | |
| 	    {
 | |
| 	       if (cs_avail_out == 0) {
 | |
| 		  c_state_out_len = 1; goto return_notr;
 | |
| 	       };
 | |
| 	       *( (UChar*)(cs_next_out) ) = c_state_out_ch;
 | |
| 	       BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
 | |
| 	       cs_next_out++;
 | |
| 	       cs_avail_out--;
 | |
| 	    }
 | |
| 	 }
 | |
| 	 /* can a new run be started? */
 | |
| 	 if (c_nblock_used == s_save_nblockPP) {
 | |
| 	    c_state_out_len = 0; goto return_notr;
 | |
| 	 };
 | |
| 	 c_state_out_ch = c_k0;
 | |
| 	 BZ_GET_FAST_C(k1); c_nblock_used++;
 | |
| 	 if (k1 != c_k0) {
 | |
| 	    c_k0 = k1; goto s_state_out_len_eq_one;
 | |
| 	 };
 | |
| 	 if (c_nblock_used == s_save_nblockPP)
 | |
| 	    goto s_state_out_len_eq_one;
 | |
| 
 | |
| 	 c_state_out_len = 2;
 | |
| 	 BZ_GET_FAST_C(k1); c_nblock_used++;
 | |
| 	 if (c_nblock_used == s_save_nblockPP) continue;
 | |
| 	 if (k1 != c_k0) { c_k0 = k1; continue; };
 | |
| 
 | |
| 	 c_state_out_len = 3;
 | |
| 	 BZ_GET_FAST_C(k1); c_nblock_used++;
 | |
| 	 if (c_nblock_used == s_save_nblockPP) continue;
 | |
| 	 if (k1 != c_k0) { c_k0 = k1; continue; };
 | |
| 
 | |
| 	 BZ_GET_FAST_C(k1); c_nblock_used++;
 | |
| 	 c_state_out_len = ((Int32)k1) + 4;
 | |
| 	 BZ_GET_FAST_C(c_k0); c_nblock_used++;
 | |
|       }
 | |
| 
 | |
|       return_notr:
 | |
|       total_out_lo32_old = s->strm->total_out_lo32;
 | |
|       s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
 | |
|       if (s->strm->total_out_lo32 < total_out_lo32_old)
 | |
| 	 s->strm->total_out_hi32++;
 | |
| 
 | |
|       /* save */
 | |
|       s->calculatedBlockCRC = c_calculatedBlockCRC;
 | |
|       s->state_out_ch       = c_state_out_ch;
 | |
|       s->state_out_len      = c_state_out_len;
 | |
|       s->nblock_used        = c_nblock_used;
 | |
|       s->k0                 = c_k0;
 | |
|       s->tt                 = c_tt;
 | |
|       s->tPos               = c_tPos;
 | |
|       s->strm->next_out     = cs_next_out;
 | |
|       s->strm->avail_out    = cs_avail_out;
 | |
|       /* end save */
 | |
|    }
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| __inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
 | |
| {
 | |
|    Int32 nb, na, mid;
 | |
|    nb = 0;
 | |
|    na = 256;
 | |
|    do {
 | |
|       mid = (nb + na) >> 1;
 | |
|       if (indx >= cftab[mid]) nb = mid; else na = mid;
 | |
|    }
 | |
|    while (na - nb != 1);
 | |
|    return nb;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| static
 | |
| void unRLE_obuf_to_output_SMALL ( DState* s )
 | |
| {
 | |
|    UChar k1;
 | |
| 
 | |
|    if (s->blockRandomised) {
 | |
| 
 | |
|       while (True) {
 | |
| 	 /* try to finish existing run */
 | |
| 	 while (True) {
 | |
| 	    if (s->strm->avail_out == 0) return;
 | |
| 	    if (s->state_out_len == 0) break;
 | |
| 	    *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
 | |
| 	    BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
 | |
| 	    s->state_out_len--;
 | |
| 	    s->strm->next_out++;
 | |
| 	    s->strm->avail_out--;
 | |
| 	    s->strm->total_out_lo32++;
 | |
| 	    if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
 | |
| 	 }
 | |
| 
 | |
| 	 /* can a new run be started? */
 | |
| 	 if (s->nblock_used == s->save_nblock+1) return;
 | |
| 
 | |
| 
 | |
| 	 s->state_out_len = 1;
 | |
| 	 s->state_out_ch = s->k0;
 | |
| 	 BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
 | |
| 	 k1 ^= BZ_RAND_MASK; s->nblock_used++;
 | |
| 	 if (s->nblock_used == s->save_nblock+1) continue;
 | |
| 	 if (k1 != s->k0) { s->k0 = k1; continue; };
 | |
| 
 | |
| 	 s->state_out_len = 2;
 | |
| 	 BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
 | |
| 	 k1 ^= BZ_RAND_MASK; s->nblock_used++;
 | |
| 	 if (s->nblock_used == s->save_nblock+1) continue;
 | |
| 	 if (k1 != s->k0) { s->k0 = k1; continue; };
 | |
| 
 | |
| 	 s->state_out_len = 3;
 | |
| 	 BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
 | |
| 	 k1 ^= BZ_RAND_MASK; s->nblock_used++;
 | |
| 	 if (s->nblock_used == s->save_nblock+1) continue;
 | |
| 	 if (k1 != s->k0) { s->k0 = k1; continue; };
 | |
| 
 | |
| 	 BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
 | |
| 	 k1 ^= BZ_RAND_MASK; s->nblock_used++;
 | |
| 	 s->state_out_len = ((Int32)k1) + 4;
 | |
| 	 BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
 | |
| 	 s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
 | |
|       }
 | |
| 
 | |
|    } else {
 | |
| 
 | |
|       while (True) {
 | |
| 	 /* try to finish existing run */
 | |
| 	 while (True) {
 | |
| 	    if (s->strm->avail_out == 0) return;
 | |
| 	    if (s->state_out_len == 0) break;
 | |
| 	    *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
 | |
| 	    BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
 | |
| 	    s->state_out_len--;
 | |
| 	    s->strm->next_out++;
 | |
| 	    s->strm->avail_out--;
 | |
| 	    s->strm->total_out_lo32++;
 | |
| 	    if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
 | |
| 	 }
 | |
| 
 | |
| 	 /* can a new run be started? */
 | |
| 	 if (s->nblock_used == s->save_nblock+1) return;
 | |
| 
 | |
| 	 s->state_out_len = 1;
 | |
| 	 s->state_out_ch = s->k0;
 | |
| 	 BZ_GET_SMALL(k1); s->nblock_used++;
 | |
| 	 if (s->nblock_used == s->save_nblock+1) continue;
 | |
| 	 if (k1 != s->k0) { s->k0 = k1; continue; };
 | |
| 
 | |
| 	 s->state_out_len = 2;
 | |
| 	 BZ_GET_SMALL(k1); s->nblock_used++;
 | |
| 	 if (s->nblock_used == s->save_nblock+1) continue;
 | |
| 	 if (k1 != s->k0) { s->k0 = k1; continue; };
 | |
| 
 | |
| 	 s->state_out_len = 3;
 | |
| 	 BZ_GET_SMALL(k1); s->nblock_used++;
 | |
| 	 if (s->nblock_used == s->save_nblock+1) continue;
 | |
| 	 if (k1 != s->k0) { s->k0 = k1; continue; };
 | |
| 
 | |
| 	 BZ_GET_SMALL(k1); s->nblock_used++;
 | |
| 	 s->state_out_len = ((Int32)k1) + 4;
 | |
| 	 BZ_GET_SMALL(s->k0); s->nblock_used++;
 | |
|       }
 | |
| 
 | |
|    }
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
 | |
| {
 | |
|    DState* s;
 | |
|    if (strm == NULL) return BZ_PARAM_ERROR;
 | |
|    s = strm->state;
 | |
|    if (s == NULL) return BZ_PARAM_ERROR;
 | |
|    if (s->strm != strm) return BZ_PARAM_ERROR;
 | |
| 
 | |
|    while (True) {
 | |
| #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
 | |
| 	WATCHDOG_RESET();
 | |
| #endif
 | |
|       if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
 | |
|       if (s->state == BZ_X_OUTPUT) {
 | |
| 	 if (s->smallDecompress)
 | |
| 	    unRLE_obuf_to_output_SMALL ( s ); else
 | |
| 	    unRLE_obuf_to_output_FAST  ( s );
 | |
| 	 if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
 | |
| 	    BZ_FINALISE_CRC ( s->calculatedBlockCRC );
 | |
| 	    if (s->verbosity >= 3)
 | |
| 	       VPrintf2 ( " {0x%x, 0x%x}", s->storedBlockCRC,
 | |
| 			  s->calculatedBlockCRC );
 | |
| 	    if (s->verbosity >= 2) VPrintf0 ( "]" );
 | |
| 	    if (s->calculatedBlockCRC != s->storedBlockCRC)
 | |
| 	       return BZ_DATA_ERROR;
 | |
| 	    s->calculatedCombinedCRC
 | |
| 	       = (s->calculatedCombinedCRC << 1) |
 | |
| 		    (s->calculatedCombinedCRC >> 31);
 | |
| 	    s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
 | |
| 	    s->state = BZ_X_BLKHDR_1;
 | |
| 	 } else {
 | |
| 	    return BZ_OK;
 | |
| 	 }
 | |
|       }
 | |
|       if (s->state >= BZ_X_MAGIC_1) {
 | |
| 	 Int32 r = BZ2_decompress ( s );
 | |
| 	 if (r == BZ_STREAM_END) {
 | |
| 	    if (s->verbosity >= 3)
 | |
| 	       VPrintf2 ( "\n    combined CRCs: stored = 0x%x, computed = 0x%x",
 | |
| 			  s->storedCombinedCRC, s->calculatedCombinedCRC );
 | |
| 	    if (s->calculatedCombinedCRC != s->storedCombinedCRC)
 | |
| 	       return BZ_DATA_ERROR;
 | |
| 	    return r;
 | |
| 	 }
 | |
| 	 if (s->state != BZ_X_OUTPUT) return r;
 | |
|       }
 | |
|    }
 | |
| 
 | |
|    AssertH ( 0, 6001 );
 | |
| 
 | |
|    return 0;  /*NOTREACHED*/
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| int BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
 | |
| {
 | |
|    DState* s;
 | |
|    if (strm == NULL) return BZ_PARAM_ERROR;
 | |
|    s = strm->state;
 | |
|    if (s == NULL) return BZ_PARAM_ERROR;
 | |
|    if (s->strm != strm) return BZ_PARAM_ERROR;
 | |
| 
 | |
|    if (s->tt   != NULL) BZFREE(s->tt);
 | |
|    if (s->ll16 != NULL) BZFREE(s->ll16);
 | |
|    if (s->ll4  != NULL) BZFREE(s->ll4);
 | |
| 
 | |
|    BZFREE(strm->state);
 | |
|    strm->state = NULL;
 | |
| 
 | |
|    return BZ_OK;
 | |
| }
 | |
| 
 | |
| 
 | |
| #ifndef BZ_NO_STDIO
 | |
| /*---------------------------------------------------*/
 | |
| /*--- File I/O stuff                              ---*/
 | |
| /*---------------------------------------------------*/
 | |
| 
 | |
| #define BZ_SETERR(eee)                    \
 | |
| {                                         \
 | |
|    if (bzerror != NULL) *bzerror = eee;   \
 | |
|    if (bzf != NULL) bzf->lastErr = eee;   \
 | |
| }
 | |
| 
 | |
| typedef
 | |
|    struct {
 | |
|       FILE*     handle;
 | |
|       Char      buf[BZ_MAX_UNUSED];
 | |
|       Int32     bufN;
 | |
|       Bool      writing;
 | |
|       bz_stream strm;
 | |
|       Int32     lastErr;
 | |
|       Bool      initialisedOk;
 | |
|    }
 | |
|    bzFile;
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------*/
 | |
| static Bool myfeof ( FILE* f )
 | |
| {
 | |
|    Int32 c = fgetc ( f );
 | |
|    if (c == EOF) return True;
 | |
|    ungetc ( c, f );
 | |
|    return False;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| BZFILE* BZ_API(BZ2_bzWriteOpen)
 | |
| 		    ( int*  bzerror,
 | |
| 		      FILE* f,
 | |
| 		      int   blockSize100k,
 | |
| 		      int   verbosity,
 | |
| 		      int   workFactor )
 | |
| {
 | |
|    Int32   ret;
 | |
|    bzFile* bzf = NULL;
 | |
| 
 | |
|    BZ_SETERR(BZ_OK);
 | |
| 
 | |
|    if (f == NULL ||
 | |
|        (blockSize100k < 1 || blockSize100k > 9) ||
 | |
|        (workFactor < 0 || workFactor > 250) ||
 | |
|        (verbosity < 0 || verbosity > 4))
 | |
|       { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
 | |
| 
 | |
|    if (ferror(f))
 | |
|       { BZ_SETERR(BZ_IO_ERROR); return NULL; };
 | |
| 
 | |
|    bzf = malloc ( sizeof(bzFile) );
 | |
|    if (bzf == NULL)
 | |
|       { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
 | |
| 
 | |
|    BZ_SETERR(BZ_OK);
 | |
|    bzf->initialisedOk = False;
 | |
|    bzf->bufN          = 0;
 | |
|    bzf->handle        = f;
 | |
|    bzf->writing       = True;
 | |
|    bzf->strm.bzalloc  = NULL;
 | |
|    bzf->strm.bzfree   = NULL;
 | |
|    bzf->strm.opaque   = NULL;
 | |
| 
 | |
|    if (workFactor == 0) workFactor = 30;
 | |
|    ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
 | |
| 			      verbosity, workFactor );
 | |
|    if (ret != BZ_OK)
 | |
|       { BZ_SETERR(ret); free(bzf); return NULL; };
 | |
| 
 | |
|    bzf->strm.avail_in = 0;
 | |
|    bzf->initialisedOk = True;
 | |
|    return bzf;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| void BZ_API(BZ2_bzWrite)
 | |
| 	     ( int*    bzerror,
 | |
| 	       BZFILE* b,
 | |
| 	       void*   buf,
 | |
| 	       int     len )
 | |
| {
 | |
|    Int32 n, n2, ret;
 | |
|    bzFile* bzf = (bzFile*)b;
 | |
| 
 | |
|    BZ_SETERR(BZ_OK);
 | |
|    if (bzf == NULL || buf == NULL || len < 0)
 | |
|       { BZ_SETERR(BZ_PARAM_ERROR); return; };
 | |
|    if (!(bzf->writing))
 | |
|       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
 | |
|    if (ferror(bzf->handle))
 | |
|       { BZ_SETERR(BZ_IO_ERROR); return; };
 | |
| 
 | |
|    if (len == 0)
 | |
|       { BZ_SETERR(BZ_OK); return; };
 | |
| 
 | |
|    bzf->strm.avail_in = len;
 | |
|    bzf->strm.next_in  = buf;
 | |
| 
 | |
|    while (True) {
 | |
|       bzf->strm.avail_out = BZ_MAX_UNUSED;
 | |
|       bzf->strm.next_out = bzf->buf;
 | |
|       ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
 | |
|       if (ret != BZ_RUN_OK)
 | |
| 	 { BZ_SETERR(ret); return; };
 | |
| 
 | |
|       if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
 | |
| 	 n = BZ_MAX_UNUSED - bzf->strm.avail_out;
 | |
| 	 n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
 | |
| 		       n, bzf->handle );
 | |
| 	 if (n != n2 || ferror(bzf->handle))
 | |
| 	    { BZ_SETERR(BZ_IO_ERROR); return; };
 | |
|       }
 | |
| 
 | |
|       if (bzf->strm.avail_in == 0)
 | |
| 	 { BZ_SETERR(BZ_OK); return; };
 | |
|    }
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| void BZ_API(BZ2_bzWriteClose)
 | |
| 		  ( int*          bzerror,
 | |
| 		    BZFILE*       b,
 | |
| 		    int           abandon,
 | |
| 		    unsigned int* nbytes_in,
 | |
| 		    unsigned int* nbytes_out )
 | |
| {
 | |
|    BZ2_bzWriteClose64 ( bzerror, b, abandon,
 | |
| 			nbytes_in, NULL, nbytes_out, NULL );
 | |
| }
 | |
| 
 | |
| 
 | |
| void BZ_API(BZ2_bzWriteClose64)
 | |
| 		  ( int*          bzerror,
 | |
| 		    BZFILE*       b,
 | |
| 		    int           abandon,
 | |
| 		    unsigned int* nbytes_in_lo32,
 | |
| 		    unsigned int* nbytes_in_hi32,
 | |
| 		    unsigned int* nbytes_out_lo32,
 | |
| 		    unsigned int* nbytes_out_hi32 )
 | |
| {
 | |
|    Int32   n, n2, ret;
 | |
|    bzFile* bzf = (bzFile*)b;
 | |
| 
 | |
|    if (bzf == NULL)
 | |
|       { BZ_SETERR(BZ_OK); return; };
 | |
|    if (!(bzf->writing))
 | |
|       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
 | |
|    if (ferror(bzf->handle))
 | |
|       { BZ_SETERR(BZ_IO_ERROR); return; };
 | |
| 
 | |
|    if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
 | |
|    if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
 | |
|    if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
 | |
|    if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
 | |
| 
 | |
|    if ((!abandon) && bzf->lastErr == BZ_OK) {
 | |
|       while (True) {
 | |
| 	 bzf->strm.avail_out = BZ_MAX_UNUSED;
 | |
| 	 bzf->strm.next_out = bzf->buf;
 | |
| 	 ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
 | |
| 	 if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
 | |
| 	    { BZ_SETERR(ret); return; };
 | |
| 
 | |
| 	 if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
 | |
| 	    n = BZ_MAX_UNUSED - bzf->strm.avail_out;
 | |
| 	    n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
 | |
| 			  n, bzf->handle );
 | |
| 	    if (n != n2 || ferror(bzf->handle))
 | |
| 	       { BZ_SETERR(BZ_IO_ERROR); return; };
 | |
| 	 }
 | |
| 
 | |
| 	 if (ret == BZ_STREAM_END) break;
 | |
|       }
 | |
|    }
 | |
| 
 | |
|    if ( !abandon && !ferror ( bzf->handle ) ) {
 | |
|       fflush ( bzf->handle );
 | |
|       if (ferror(bzf->handle))
 | |
| 	 { BZ_SETERR(BZ_IO_ERROR); return; };
 | |
|    }
 | |
| 
 | |
|    if (nbytes_in_lo32 != NULL)
 | |
|       *nbytes_in_lo32 = bzf->strm.total_in_lo32;
 | |
|    if (nbytes_in_hi32 != NULL)
 | |
|       *nbytes_in_hi32 = bzf->strm.total_in_hi32;
 | |
|    if (nbytes_out_lo32 != NULL)
 | |
|       *nbytes_out_lo32 = bzf->strm.total_out_lo32;
 | |
|    if (nbytes_out_hi32 != NULL)
 | |
|       *nbytes_out_hi32 = bzf->strm.total_out_hi32;
 | |
| 
 | |
|    BZ_SETERR(BZ_OK);
 | |
|    BZ2_bzCompressEnd ( &(bzf->strm) );
 | |
|    free ( bzf );
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| BZFILE* BZ_API(BZ2_bzReadOpen)
 | |
| 		   ( int*  bzerror,
 | |
| 		     FILE* f,
 | |
| 		     int   verbosity,
 | |
| 		     int   small,
 | |
| 		     void* unused,
 | |
| 		     int   nUnused )
 | |
| {
 | |
|    bzFile* bzf = NULL;
 | |
|    int     ret;
 | |
| 
 | |
|    BZ_SETERR(BZ_OK);
 | |
| 
 | |
|    if (f == NULL ||
 | |
|        (small != 0 && small != 1) ||
 | |
|        (verbosity < 0 || verbosity > 4) ||
 | |
|        (unused == NULL && nUnused != 0) ||
 | |
|        (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
 | |
|       { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
 | |
| 
 | |
|    if (ferror(f))
 | |
|       { BZ_SETERR(BZ_IO_ERROR); return NULL; };
 | |
| 
 | |
|    bzf = malloc ( sizeof(bzFile) );
 | |
|    if (bzf == NULL)
 | |
|       { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
 | |
| 
 | |
|    BZ_SETERR(BZ_OK);
 | |
| 
 | |
|    bzf->initialisedOk = False;
 | |
|    bzf->handle        = f;
 | |
|    bzf->bufN          = 0;
 | |
|    bzf->writing       = False;
 | |
|    bzf->strm.bzalloc  = NULL;
 | |
|    bzf->strm.bzfree   = NULL;
 | |
|    bzf->strm.opaque   = NULL;
 | |
| 
 | |
|    while (nUnused > 0) {
 | |
|       bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
 | |
|       unused = ((void*)( 1 + ((UChar*)(unused))  ));
 | |
|       nUnused--;
 | |
|    }
 | |
| 
 | |
|    ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
 | |
|    if (ret != BZ_OK)
 | |
|       { BZ_SETERR(ret); free(bzf); return NULL; };
 | |
| 
 | |
|    bzf->strm.avail_in = bzf->bufN;
 | |
|    bzf->strm.next_in  = bzf->buf;
 | |
| 
 | |
|    bzf->initialisedOk = True;
 | |
|    return bzf;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
 | |
| {
 | |
|    bzFile* bzf = (bzFile*)b;
 | |
| 
 | |
|    BZ_SETERR(BZ_OK);
 | |
|    if (bzf == NULL)
 | |
|       { BZ_SETERR(BZ_OK); return; };
 | |
| 
 | |
|    if (bzf->writing)
 | |
|       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
 | |
| 
 | |
|    if (bzf->initialisedOk)
 | |
|       (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
 | |
|    free ( bzf );
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| int BZ_API(BZ2_bzRead)
 | |
| 	   ( int*    bzerror,
 | |
| 	     BZFILE* b,
 | |
| 	     void*   buf,
 | |
| 	     int     len )
 | |
| {
 | |
|    Int32   n, ret;
 | |
|    bzFile* bzf = (bzFile*)b;
 | |
| 
 | |
|    BZ_SETERR(BZ_OK);
 | |
| 
 | |
|    if (bzf == NULL || buf == NULL || len < 0)
 | |
|       { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
 | |
| 
 | |
|    if (bzf->writing)
 | |
|       { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
 | |
| 
 | |
|    if (len == 0)
 | |
|       { BZ_SETERR(BZ_OK); return 0; };
 | |
| 
 | |
|    bzf->strm.avail_out = len;
 | |
|    bzf->strm.next_out = buf;
 | |
| 
 | |
|    while (True) {
 | |
| 
 | |
|       if (ferror(bzf->handle))
 | |
| 	 { BZ_SETERR(BZ_IO_ERROR); return 0; };
 | |
| 
 | |
|       if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
 | |
| 	 n = fread ( bzf->buf, sizeof(UChar),
 | |
| 		     BZ_MAX_UNUSED, bzf->handle );
 | |
| 	 if (ferror(bzf->handle))
 | |
| 	    { BZ_SETERR(BZ_IO_ERROR); return 0; };
 | |
| 	 bzf->bufN = n;
 | |
| 	 bzf->strm.avail_in = bzf->bufN;
 | |
| 	 bzf->strm.next_in = bzf->buf;
 | |
|       }
 | |
| 
 | |
|       ret = BZ2_bzDecompress ( &(bzf->strm) );
 | |
| 
 | |
|       if (ret != BZ_OK && ret != BZ_STREAM_END)
 | |
| 	 { BZ_SETERR(ret); return 0; };
 | |
| 
 | |
|       if (ret == BZ_OK && myfeof(bzf->handle) &&
 | |
| 	  bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
 | |
| 	 { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
 | |
| 
 | |
|       if (ret == BZ_STREAM_END)
 | |
| 	 { BZ_SETERR(BZ_STREAM_END);
 | |
| 	   return len - bzf->strm.avail_out; };
 | |
|       if (bzf->strm.avail_out == 0)
 | |
| 	 { BZ_SETERR(BZ_OK); return len; };
 | |
| 
 | |
|    }
 | |
| 
 | |
|    return 0; /*not reached*/
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| void BZ_API(BZ2_bzReadGetUnused)
 | |
| 		     ( int*    bzerror,
 | |
| 		       BZFILE* b,
 | |
| 		       void**  unused,
 | |
| 		       int*    nUnused )
 | |
| {
 | |
|    bzFile* bzf = (bzFile*)b;
 | |
|    if (bzf == NULL)
 | |
|       { BZ_SETERR(BZ_PARAM_ERROR); return; };
 | |
|    if (bzf->lastErr != BZ_STREAM_END)
 | |
|       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
 | |
|    if (unused == NULL || nUnused == NULL)
 | |
|       { BZ_SETERR(BZ_PARAM_ERROR); return; };
 | |
| 
 | |
|    BZ_SETERR(BZ_OK);
 | |
|    *nUnused = bzf->strm.avail_in;
 | |
|    *unused = bzf->strm.next_in;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| /*--- Misc convenience stuff                      ---*/
 | |
| /*---------------------------------------------------*/
 | |
| #ifndef BZ_NO_COMPRESS
 | |
| /*---------------------------------------------------*/
 | |
| int BZ_API(BZ2_bzBuffToBuffCompress)
 | |
| 			 ( char*         dest,
 | |
| 			   unsigned int* destLen,
 | |
| 			   char*         source,
 | |
| 			   unsigned int  sourceLen,
 | |
| 			   int           blockSize100k,
 | |
| 			   int           verbosity,
 | |
| 			   int           workFactor )
 | |
| {
 | |
|    bz_stream strm;
 | |
|    int ret;
 | |
| 
 | |
|    if (dest == NULL || destLen == NULL ||
 | |
|        source == NULL ||
 | |
|        blockSize100k < 1 || blockSize100k > 9 ||
 | |
|        verbosity < 0 || verbosity > 4 ||
 | |
|        workFactor < 0 || workFactor > 250)
 | |
|       return BZ_PARAM_ERROR;
 | |
| 
 | |
|    if (workFactor == 0) workFactor = 30;
 | |
|    strm.bzalloc = NULL;
 | |
|    strm.bzfree = NULL;
 | |
|    strm.opaque = NULL;
 | |
|    ret = BZ2_bzCompressInit ( &strm, blockSize100k,
 | |
| 			      verbosity, workFactor );
 | |
|    if (ret != BZ_OK) return ret;
 | |
| 
 | |
|    strm.next_in = source;
 | |
|    strm.next_out = dest;
 | |
|    strm.avail_in = sourceLen;
 | |
|    strm.avail_out = *destLen;
 | |
| 
 | |
|    ret = BZ2_bzCompress ( &strm, BZ_FINISH );
 | |
|    if (ret == BZ_FINISH_OK) goto output_overflow;
 | |
|    if (ret != BZ_STREAM_END) goto errhandler;
 | |
| 
 | |
|    /* normal termination */
 | |
|    *destLen -= strm.avail_out;
 | |
|    BZ2_bzCompressEnd ( &strm );
 | |
|    return BZ_OK;
 | |
| 
 | |
|    output_overflow:
 | |
|    BZ2_bzCompressEnd ( &strm );
 | |
|    return BZ_OUTBUFF_FULL;
 | |
| 
 | |
|    errhandler:
 | |
|    BZ2_bzCompressEnd ( &strm );
 | |
|    return ret;
 | |
| }
 | |
| #endif /* BZ_NO_COMPRESS */
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| int BZ_API(BZ2_bzBuffToBuffDecompress)
 | |
| 			   ( char*         dest,
 | |
| 			     unsigned int* destLen,
 | |
| 			     char*         source,
 | |
| 			     unsigned int  sourceLen,
 | |
| 			     int           small,
 | |
| 			     int           verbosity )
 | |
| {
 | |
|    bz_stream strm;
 | |
|    int ret;
 | |
| 
 | |
|    if (destLen == NULL || source == NULL)
 | |
| 	  return BZ_PARAM_ERROR;
 | |
| 
 | |
|    strm.bzalloc = NULL;
 | |
|    strm.bzfree = NULL;
 | |
|    strm.opaque = NULL;
 | |
|    ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
 | |
|    if (ret != BZ_OK) return ret;
 | |
| 
 | |
|    strm.next_in = source;
 | |
|    strm.next_out = dest;
 | |
|    strm.avail_in = sourceLen;
 | |
|    strm.avail_out = *destLen;
 | |
| 
 | |
|    ret = BZ2_bzDecompress ( &strm );
 | |
|    *destLen -= strm.avail_out;
 | |
|    if (ret == BZ_OK) goto output_overflow_or_eof;
 | |
|    if (ret != BZ_STREAM_END) goto errhandler;
 | |
| 
 | |
|    /* normal termination */
 | |
|    BZ2_bzDecompressEnd ( &strm );
 | |
|    return BZ_OK;
 | |
| 
 | |
|    output_overflow_or_eof:
 | |
|    if (strm.avail_out > 0) {
 | |
|       BZ2_bzDecompressEnd ( &strm );
 | |
|       return BZ_UNEXPECTED_EOF;
 | |
|    } else {
 | |
|       BZ2_bzDecompressEnd ( &strm );
 | |
|       return BZ_OUTBUFF_FULL;
 | |
|    };
 | |
| 
 | |
|    errhandler:
 | |
|    BZ2_bzDecompressEnd ( &strm );
 | |
|    return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| /*--
 | |
|    Code contributed by Yoshioka Tsuneo
 | |
|    (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
 | |
|    to support better zlib compatibility.
 | |
|    This code is not _officially_ part of libbzip2 (yet);
 | |
|    I haven't tested it, documented it, or considered the
 | |
|    threading-safeness of it.
 | |
|    If this code breaks, please contact both Yoshioka and me.
 | |
| --*/
 | |
| /*---------------------------------------------------*/
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| /*--
 | |
|    return version like "0.9.0c".
 | |
| --*/
 | |
| const char * BZ_API(BZ2_bzlibVersion)(void)
 | |
| {
 | |
|    return BZ_VERSION;
 | |
| }
 | |
| 
 | |
| 
 | |
| #ifndef BZ_NO_STDIO
 | |
| /*---------------------------------------------------*/
 | |
| 
 | |
| #if defined(_WIN32) || defined(OS2) || defined(MSDOS)
 | |
| #   include <fcntl.h>
 | |
| #   include <io.h>
 | |
| #   define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
 | |
| #else
 | |
| #   define SET_BINARY_MODE(file)
 | |
| #endif
 | |
| static
 | |
| BZFILE * bzopen_or_bzdopen
 | |
| 	       ( const char *path,   /* no use when bzdopen */
 | |
| 		 int fd,             /* no use when bzdopen */
 | |
| 		 const char *mode,
 | |
| 		 int open_mode)      /* bzopen: 0, bzdopen:1 */
 | |
| {
 | |
|    int    bzerr;
 | |
|    char   unused[BZ_MAX_UNUSED];
 | |
|    int    blockSize100k = 9;
 | |
|    int    writing       = 0;
 | |
|    char   mode2[10]     = "";
 | |
|    FILE   *fp           = NULL;
 | |
|    BZFILE *bzfp         = NULL;
 | |
|    int    verbosity     = 0;
 | |
|    int    workFactor    = 30;
 | |
|    int    smallMode     = 0;
 | |
|    int    nUnused       = 0;
 | |
| 
 | |
|    if (mode == NULL) return NULL;
 | |
|    while (*mode) {
 | |
|       switch (*mode) {
 | |
|       case 'r':
 | |
| 	 writing = 0; break;
 | |
|       case 'w':
 | |
| 	 writing = 1; break;
 | |
|       case 's':
 | |
| 	 smallMode = 1; break;
 | |
|       default:
 | |
| 	 if (isdigit((int)(*mode))) {
 | |
| 	    blockSize100k = *mode-BZ_HDR_0;
 | |
| 	 }
 | |
|       }
 | |
|       mode++;
 | |
|    }
 | |
|    strcat(mode2, writing ? "w" : "r" );
 | |
|    strcat(mode2,"b");   /* binary mode */
 | |
| 
 | |
|    if (open_mode==0) {
 | |
|       if (path==NULL || strcmp(path,"")==0) {
 | |
| 	fp = (writing ? stdout : stdin);
 | |
| 	SET_BINARY_MODE(fp);
 | |
|       } else {
 | |
| 	fp = fopen(path,mode2);
 | |
|       }
 | |
|    } else {
 | |
| #ifdef BZ_STRICT_ANSI
 | |
|       fp = NULL;
 | |
| #else
 | |
|       fp = fdopen(fd,mode2);
 | |
| #endif
 | |
|    }
 | |
|    if (fp == NULL) return NULL;
 | |
| 
 | |
|    if (writing) {
 | |
|       /* Guard against total chaos and anarchy -- JRS */
 | |
|       if (blockSize100k < 1) blockSize100k = 1;
 | |
|       if (blockSize100k > 9) blockSize100k = 9;
 | |
|       bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
 | |
| 			     verbosity,workFactor);
 | |
|    } else {
 | |
|       bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
 | |
| 			    unused,nUnused);
 | |
|    }
 | |
|    if (bzfp == NULL) {
 | |
|       if (fp != stdin && fp != stdout) fclose(fp);
 | |
|       return NULL;
 | |
|    }
 | |
|    return bzfp;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| /*--
 | |
|    open file for read or write.
 | |
|       ex) bzopen("file","w9")
 | |
|       case path="" or NULL => use stdin or stdout.
 | |
| --*/
 | |
| BZFILE * BZ_API(BZ2_bzopen)
 | |
| 	       ( const char *path,
 | |
| 		 const char *mode )
 | |
| {
 | |
|    return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| BZFILE * BZ_API(BZ2_bzdopen)
 | |
| 	       ( int fd,
 | |
| 		 const char *mode )
 | |
| {
 | |
|    return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
 | |
| {
 | |
|    int bzerr, nread;
 | |
|    if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
 | |
|    nread = BZ2_bzRead(&bzerr,b,buf,len);
 | |
|    if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
 | |
|       return nread;
 | |
|    } else {
 | |
|       return -1;
 | |
|    }
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
 | |
| {
 | |
|    int bzerr;
 | |
| 
 | |
|    BZ2_bzWrite(&bzerr,b,buf,len);
 | |
|    if(bzerr == BZ_OK){
 | |
|       return len;
 | |
|    }else{
 | |
|       return -1;
 | |
|    }
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| int BZ_API(BZ2_bzflush) (BZFILE *b)
 | |
| {
 | |
|    /* do nothing now... */
 | |
|    return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| void BZ_API(BZ2_bzclose) (BZFILE* b)
 | |
| {
 | |
|    int bzerr;
 | |
|    FILE *fp = ((bzFile *)b)->handle;
 | |
| 
 | |
|    if (b==NULL) {return;}
 | |
|    if(((bzFile*)b)->writing){
 | |
|       BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
 | |
|       if(bzerr != BZ_OK){
 | |
| 	 BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
 | |
|       }
 | |
|    }else{
 | |
|       BZ2_bzReadClose(&bzerr,b);
 | |
|    }
 | |
|    if(fp!=stdin && fp!=stdout){
 | |
|       fclose(fp);
 | |
|    }
 | |
| }
 | |
| 
 | |
| 
 | |
| /*---------------------------------------------------*/
 | |
| /*--
 | |
|    return last error code
 | |
| --*/
 | |
| static char *bzerrorstrings[] = {
 | |
|        "OK"
 | |
|       ,"SEQUENCE_ERROR"
 | |
|       ,"PARAM_ERROR"
 | |
|       ,"MEM_ERROR"
 | |
|       ,"DATA_ERROR"
 | |
|       ,"DATA_ERROR_MAGIC"
 | |
|       ,"IO_ERROR"
 | |
|       ,"UNEXPECTED_EOF"
 | |
|       ,"OUTBUFF_FULL"
 | |
|       ,"CONFIG_ERROR"
 | |
|       ,"???"   /* for future */
 | |
|       ,"???"   /* for future */
 | |
|       ,"???"   /* for future */
 | |
|       ,"???"   /* for future */
 | |
|       ,"???"   /* for future */
 | |
|       ,"???"   /* for future */
 | |
| };
 | |
| 
 | |
| 
 | |
| const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
 | |
| {
 | |
|    int err = ((bzFile *)b)->lastErr;
 | |
| 
 | |
|    if(err>0) err = 0;
 | |
|    *errnum = err;
 | |
|    return bzerrorstrings[err*-1];
 | |
| }
 | |
| #endif
 | |
| 
 | |
| void bz_internal_error(int errcode)
 | |
| {
 | |
| 	printf ("BZIP2 internal error %d\n", errcode);
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------*/
 | |
| /*--- end                                           bzlib.c ---*/
 | |
| /*-------------------------------------------------------------*/
 |