bunzip: small code shrink and consmetics

read_bunzip                                          276     283      +7
get_bits                                             184     162     -22
get_next_block                                      1833    1810     -23
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/2 up/down: 7/-45)             Total: -38 bytes
This commit is contained in:
Denis Vlasenko
2007-10-10 20:53:41 +00:00
parent db60bcf1b7
commit 52a4388d95

View File

@@ -44,7 +44,7 @@
#define RETVAL_LAST_BLOCK (-1) #define RETVAL_LAST_BLOCK (-1)
#define RETVAL_NOT_BZIP_DATA (-2) #define RETVAL_NOT_BZIP_DATA (-2)
#define RETVAL_UNEXPECTED_INPUT_EOF (-3) #define RETVAL_UNEXPECTED_INPUT_EOF (-3)
#define RETVAL_UNEXPECTED_OUTPUT_EOF (-4) #define RETVAL_SHORT_WRITE (-4)
#define RETVAL_DATA_ERROR (-5) #define RETVAL_DATA_ERROR (-5)
#define RETVAL_OUT_OF_MEMORY (-6) #define RETVAL_OUT_OF_MEMORY (-6)
#define RETVAL_OBSOLETE_INPUT (-7) #define RETVAL_OBSOLETE_INPUT (-7)
@@ -54,22 +54,27 @@
/* This is what we know about each Huffman coding group */ /* This is what we know about each Huffman coding group */
struct group_data { struct group_data {
/* We have an extra slot at the end of limit[] for a sentinal value. */ /* We have an extra slot at the end of limit[] for a sentinel value. */
int limit[MAX_HUFCODE_BITS+1], base[MAX_HUFCODE_BITS], permute[MAX_SYMBOLS]; int limit[MAX_HUFCODE_BITS+1], base[MAX_HUFCODE_BITS], permute[MAX_SYMBOLS];
int minLen, maxLen; int minLen, maxLen;
}; };
/* Structure holding all the housekeeping data, including IO buffers and /* Structure holding all the housekeeping data, including IO buffers and
memory that persists between calls to bunzip */ * memory that persists between calls to bunzip
* Found the most used member:
* cat this_file.c | sed -e 's/"/ /g' -e "s/'/ /g" | xargs -n1 \
* | grep 'bd->' | sed 's/^.*bd->/bd->/' | sort | $PAGER
* and moved it (inbufBitCount) to offset 0.
*/
struct bunzip_data { struct bunzip_data {
/* State for interrupting output loop */
int writeCopies, writePos, writeRunCountdown, writeCount, writeCurrent;
/* I/O tracking data (file handles, buffers, positions, etc.) */ /* I/O tracking data (file handles, buffers, positions, etc.) */
unsigned inbufBitCount, inbufBits;
int in_fd, out_fd, inbufCount, inbufPos /*, outbufPos*/; int in_fd, out_fd, inbufCount, inbufPos /*, outbufPos*/;
unsigned char *inbuf /*,*outbuf*/; unsigned char *inbuf /*,*outbuf*/;
unsigned inbufBitCount, inbufBits;
/* State for interrupting output loop */
int writeCopies, writePos, writeRunCountdown, writeCount, writeCurrent;
/* The CRC values stored in the block header and calculated from the data */ /* The CRC values stored in the block header and calculated from the data */
uint32_t headerCRC, totalCRC, writeCRC; uint32_t headerCRC, totalCRC, writeCRC;
@@ -80,7 +85,7 @@ struct bunzip_data {
/* For I/O error handling */ /* For I/O error handling */
jmp_buf jmpbuf; jmp_buf jmpbuf;
/* Big things go last (register-relative addressing can be larger for big offsets */ /* Big things go last (register-relative addressing can be larger for big offsets) */
uint32_t crc32Table[256]; uint32_t crc32Table[256];
unsigned char selectors[32768]; /* nSelectors=15 bits */ unsigned char selectors[32768]; /* nSelectors=15 bits */
struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */ struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */
@@ -91,7 +96,7 @@ struct bunzip_data {
/* Return the next nnn bits of input. All reads from the compressed input /* Return the next nnn bits of input. All reads from the compressed input
are done through this function. All reads are big endian */ are done through this function. All reads are big endian */
static unsigned get_bits(bunzip_data *bd, char bits_wanted) static unsigned get_bits(bunzip_data *bd, int bits_wanted)
{ {
unsigned bits = 0; unsigned bits = 0;
@@ -320,7 +325,7 @@ static int get_next_block(bunzip_data *bd)
t += temp[i]; t += temp[i];
base[i+1] = pp - t; base[i+1] = pp - t;
} }
limit[maxLen+1] = INT_MAX; /* Sentinal value for reading next sym. */ limit[maxLen+1] = INT_MAX; /* Sentinel value for reading next sym. */
limit[maxLen] = pp + temp[maxLen] - 1; limit[maxLen] = pp + temp[maxLen] - 1;
base[minLen] = 0; base[minLen] = 0;
} }
@@ -331,8 +336,9 @@ static int get_next_block(bunzip_data *bd)
/* Initialize symbol occurrence counters and symbol Move To Front table */ /* Initialize symbol occurrence counters and symbol Move To Front table */
memset(byteCount, 0, sizeof(byteCount)); /* smaller, maybe slower? */
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++) {
byteCount[i] = 0; //byteCount[i] = 0;
mtfSymbol[i] = (unsigned char)i; mtfSymbol[i] = (unsigned char)i;
} }
@@ -573,8 +579,8 @@ int read_bunzip(bunzip_data *bd, char *outbuf, int len)
current = pos & 0xff; current = pos & 0xff;
pos >>= 8; pos >>= 8;
/* After 3 consecutive copies of the same byte, the 4th is a repeat /* After 3 consecutive copies of the same byte, the 4th
count. We count down from 4 instead * is a repeat count. We count down from 4 instead
* of counting up because testing for non-zero is faster */ * of counting up because testing for non-zero is faster */
if (--bd->writeRunCountdown) { if (--bd->writeRunCountdown) {
@@ -713,8 +719,8 @@ unpack_bz2_stream(int src_fd, int dst_fd)
for (;;) { for (;;) {
i = read_bunzip(bd, outbuf, IOBUF_SIZE); i = read_bunzip(bd, outbuf, IOBUF_SIZE);
if (i <= 0) break; if (i <= 0) break;
if (i != safe_write(dst_fd, outbuf, i)) { if (i != full_write(dst_fd, outbuf, i)) {
i = RETVAL_UNEXPECTED_OUTPUT_EOF; i = RETVAL_SHORT_WRITE;
break; break;
} }
USE_DESKTOP(total_written += i;) USE_DESKTOP(total_written += i;)
@@ -729,8 +735,8 @@ unpack_bz2_stream(int src_fd, int dst_fd)
} else { } else {
i = RETVAL_OK; i = RETVAL_OK;
} }
} else if (i == RETVAL_UNEXPECTED_OUTPUT_EOF) { } else if (i == RETVAL_SHORT_WRITE) {
bb_error_msg("unexpected EOF"); bb_error_msg("short write");
} else { } else {
bb_error_msg("bunzip error %d", i); bb_error_msg("bunzip error %d", i);
} }