|  | #include <config.h> | 
|  | #include <common.h> | 
|  | #include <watchdog.h> | 
|  | #ifdef CONFIG_BZIP2 | 
|  |  | 
|  | /* | 
|  | * 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 ); | 
|  | if (ret == BZ_OK) goto output_overflow_or_eof; | 
|  | if (ret != BZ_STREAM_END) goto errhandler; | 
|  |  | 
|  | /* normal termination */ | 
|  | *destLen -= strm.avail_out; | 
|  | 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 | 
|  |  | 
|  |  | 
|  | /*-------------------------------------------------------------*/ | 
|  | /*--- end                                           bzlib.c ---*/ | 
|  | /*-------------------------------------------------------------*/ | 
|  |  | 
|  | #endif /* CONFIG_BZIP2 */ |