libbb: introduce and use common crc32 routine
authorDenys Vlasenko <dvlasenk@redhat.com>
Wed, 27 Oct 2010 13:26:45 +0000 (15:26 +0200)
committerDenys Vlasenko <dvlasenk@redhat.com>
Wed, 27 Oct 2010 13:26:45 +0000 (15:26 +0200)
function                                             old     new   delta
crc32_block_endian1                                    -      37     +37
crc32_block_endian0                                    -      34     +34
global_crc32_table                                     -       8      +8
file_read                                             82      87      +5
gzip_main                                            211     214      +3
xz_crc32                                              40      35      -5
crc32_table                                            8       -      -8
calculate_gunzip_crc                                  54      34     -20
lzo_crc32                                             54      25     -29
cksum_main                                           298     211     -87
------------------------------------------------------------------------------
(add/remove: 3/1 grow/shrink: 2/4 up/down: 87/-149)           Total: -62 bytes

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
archival/gzip.c
archival/libunarchive/decompress_unxz.c
archival/libunarchive/decompress_unzip.c
archival/lzop.c
coreutils/cksum.c
include/libbb.h
libbb/crc32.c
miscutils/flash_eraseall.c
util-linux/fdisk_gpt.c

index 32528d9..4d39906 100644 (file)
@@ -340,7 +340,7 @@ struct globals {
        ulg bits_sent;                  /* bit length of the compressed data */
 #endif
 
-       uint32_t *crc_32_tab;
+       /*uint32_t *crc_32_tab;*/
        uint32_t crc;   /* shift register contents */
 };
 
@@ -393,15 +393,9 @@ static void put_32bit(ulg n)
  * pointer, then initialize the crc shift register contents instead.
  * Return the current crc in either case.
  */
-static uint32_t updcrc(uch * s, unsigned n)
+static void updcrc(uch * s, unsigned n)
 {
-       uint32_t c = G1.crc;
-       while (n) {
-               c = G1.crc_32_tab[(uch)(c ^ *s++)] ^ (c >> 8);
-               n--;
-       }
-       G1.crc = c;
-       return c;
+       G1.crc = crc32_block_endian0(G1.crc, s, n, global_crc32_table /*G1.crc_32_tab*/);
 }
 
 
@@ -2104,8 +2098,8 @@ int gzip_main(int argc UNUSED_PARAM, char **argv)
        ALLOC(uch, G1.window, 2L * WSIZE);
        ALLOC(ush, G1.prev, 1L << BITS);
 
-       /* Initialise the CRC32 table */
-       G1.crc_32_tab = crc32_filltable(NULL, 0);
+       /* Initialize the CRC32 table */
+       global_crc32_table = crc32_filltable(NULL, 0);
 
        return bbunpack(argv, pack_gzip, append_ext, "gz");
 }
index faba9ca..ca42723 100644 (file)
 
 /* We use our own crc32 function */
 #define XZ_INTERNAL_CRC32 0
-static uint32_t *crc32_table;
 static uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc)
 {
-       crc = ~crc;
-
-       while (size != 0) {
-               crc = crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
-               --size;
-       }
-
-       return ~crc;
+       return ~crc32_block_endian0(~crc, buf, size, global_crc32_table);
 }
 
 /* We use arch-optimized unaligned accessors */
@@ -53,8 +45,8 @@ unpack_xz_stream(int src_fd, int dst_fd)
        unsigned char *membuf;
        IF_DESKTOP(long long) int total = 0;
 
-       if (!crc32_table)
-               crc32_table = crc32_filltable(NULL, /*endian:*/ 0);
+       if (!global_crc32_table)
+               global_crc32_table = crc32_filltable(NULL, /*endian:*/ 0);
 
        memset(&iobuf, 0, sizeof(iobuf));
        /* Preload XZ file signature */
index 20fda9d..cb8a3d7 100644 (file)
@@ -925,10 +925,7 @@ static int inflate_block(STATE_PARAM smallint *e)
 /* Two callsites, both in inflate_get_next_window */
 static void calculate_gunzip_crc(STATE_PARAM_ONLY)
 {
-       unsigned n;
-       for (n = 0; n < gunzip_outbuf_count; n++) {
-               gunzip_crc = gunzip_crc_table[((int) gunzip_crc ^ (gunzip_window[n])) & 0xff] ^ (gunzip_crc >> 8);
-       }
+       gunzip_crc = crc32_block_endian0(gunzip_crc, gunzip_window, gunzip_outbuf_count, gunzip_crc_table);
        gunzip_bytes_out += gunzip_outbuf_count;
 }
 
index c6e718a..acb34fe 100644 (file)
@@ -393,7 +393,7 @@ typedef struct header_t {
 } header_t;
 
 struct globals {
-       const uint32_t *lzo_crc32_table;
+       /*const uint32_t *lzo_crc32_table;*/
        chksum_t chksum_in;
        chksum_t chksum_out;
 } FIX_ALIASING;
@@ -468,19 +468,10 @@ lzo_adler32(uint32_t adler, const uint8_t* buf, unsigned len)
 static FAST_FUNC uint32_t
 lzo_crc32(uint32_t c, const uint8_t* buf, unsigned len)
 {
-       uint32_t crc;
+       //if (buf == NULL) - impossible
+       //      return 0;
 
-       if (buf == NULL)
-               return 0;
-
-       crc = ~c;
-       if (len != 0) do {
-               crc = G.lzo_crc32_table[(uint8_t)((int)crc ^ *buf)] ^ (crc >> 8);
-               buf += 1;
-               len -= 1;
-       } while (len > 0);
-
-       return ~crc;
+       return ~crc32_block_endian0(~c, buf, len, global_crc32_table);
 }
 
 /**********************************************************************/
@@ -679,8 +670,7 @@ static NOINLINE smallint lzo_compress(const header_t *h)
                if (dst_len < src_len) {
                        /* write checksum of compressed block */
                        if (h->flags & F_ADLER32_C)
-                               write32(lzo_adler32(ADLER32_INIT_VALUE, b2,
-                                                       dst_len));
+                               write32(lzo_adler32(ADLER32_INIT_VALUE, b2, dst_len));
                        if (h->flags & F_CRC32_C)
                                write32(lzo_crc32(CRC32_INIT_VALUE, b2, dst_len));
                        /* write compressed block data */
@@ -1080,6 +1070,6 @@ int lzop_main(int argc UNUSED_PARAM, char **argv)
        if (applet_name[0] == 'u')
                option_mask32 |= OPT_DECOMPRESS;
 
-       G.lzo_crc32_table = crc32_filltable(NULL, 0);
+       global_crc32_table = crc32_filltable(NULL, 0);
        return bbunpack(argv, pack_lzop, make_new_name_lzop, /*unused:*/ NULL);
 }
index 7bf383e..7a37e6a 100644 (file)
@@ -18,7 +18,6 @@ int cksum_main(int argc UNUSED_PARAM, char **argv)
        off_t length, filesize;
        int bytes_read;
        int exit_code = EXIT_SUCCESS;
-       uint8_t *cp;
 
 #if ENABLE_DESKTOP
        getopt32(argv, ""); /* coreutils 6.9 compat */
@@ -39,11 +38,7 @@ int cksum_main(int argc UNUSED_PARAM, char **argv)
 
 #define read_buf bb_common_bufsiz1
                while ((bytes_read = safe_read(fd, read_buf, sizeof(read_buf))) > 0) {
-                       cp = (uint8_t *) read_buf;
-                       length += bytes_read;
-                       do {
-                               crc = (crc << 8) ^ crc32_table[(crc >> 24) ^ *cp++];
-                       } while (--bytes_read);
+                       crc = crc32_block_endian1(crc, read_buf, bytes_read, crc32_table);
                }
                close(fd);
 
index d14728e..587a5f9 100644 (file)
@@ -1543,11 +1543,10 @@ void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
 void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
 void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC;
 
-/* TODO: add global crc32_table pointer and create
- * LE and BE functions to calculate crc32 over given bytes.
- * Currently we have about five reimplementations...
- */
+extern uint32_t *global_crc32_table;
 uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC;
+uint32_t crc32_block_endian1(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table) FAST_FUNC;
+uint32_t crc32_block_endian0(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table) FAST_FUNC;
 
 typedef struct masks_labels_t {
        const char *labels;
index 520b1ff..2cc6ea7 100644 (file)
@@ -18,6 +18,8 @@
 
 #include "libbb.h"
 
+uint32_t *global_crc32_table;
+
 uint32_t* FAST_FUNC crc32_filltable(uint32_t *crc_table, int endian)
 {
        uint32_t polynomial = endian ? 0x04c11db7 : 0xedb88320;
@@ -40,3 +42,25 @@ uint32_t* FAST_FUNC crc32_filltable(uint32_t *crc_table, int endian)
 
        return crc_table - 256;
 }
+
+uint32_t FAST_FUNC crc32_block_endian1(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table)
+{
+       const void *end = (uint8_t*)buf + len;
+
+       while (buf != end) {
+               val = (val << 8) ^ crc_table[(val >> 24) ^ *(uint8_t*)buf];
+               buf = (uint8_t*)buf + 1;
+       }
+       return val;
+}
+
+uint32_t FAST_FUNC crc32_block_endian0(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table)
+{
+       const void *end = (uint8_t*)buf + len;
+
+       while (buf != end) {
+                val = crc_table        [(uint8_t)val ^ *(uint8_t*)buf] ^ (val >> 8);
+               buf = (uint8_t*)buf + 1;
+       }
+       return val;
+}
index 53aad3d..b832cc1 100644 (file)
@@ -42,15 +42,6 @@ but mtd/jffs2-user.h is gone now (at least 2.6.31.6 does not have it anymore)
 #define cpu_to_je16(v) ((jint16_t){(v)})
 #define cpu_to_je32(v) ((jint32_t){(v)})
 
-static uint32_t crc32(uint32_t val, const void *ss, int len,
-               uint32_t *crc32_table)
-{
-       const unsigned char *s = ss;
-       while (--len >= 0)
-               val = crc32_table[(val ^ *s++) & 0xff] ^ (val >> 8);
-       return val;
-}
-
 static void show_progress(mtd_info_t *meminfo, erase_info_t *erase)
 {
        printf("\rErasing %u Kibyte @ %x - %2u%% complete.",
@@ -131,8 +122,9 @@ int flash_eraseall_main(int argc UNUSED_PARAM, char **argv)
                        cleanmarker.totlen = cpu_to_je32(8);
                }
 
-               cleanmarker.hdr_crc = cpu_to_je32(crc32(0, &cleanmarker, sizeof(struct jffs2_unknown_node) - 4,
-                                       crc32_table));
+               cleanmarker.hdr_crc = cpu_to_je32(
+                       crc32_block_endian0(0, &cleanmarker, sizeof(struct jffs2_unknown_node) - 4, crc32_table)
+               );
        }
 
        /* Don't want to destroy progress indicator by bb_error_msg's */
index 98803ec..4dfb5b2 100644 (file)
@@ -46,8 +46,6 @@ static unsigned int n_parts;
 static unsigned int part_array_len;
 static unsigned int part_entry_len;
 
-static uint32_t *crc32_table;
-
 static inline gpt_partition *
 gpt_part(int i)
 {
@@ -61,12 +59,7 @@ gpt_part(int i)
 static uint32_t
 gpt_crc32(void *buf, int len)
 {
-       uint32_t crc = 0xffffffff;
-
-       for (; len > 0; len--, buf++) {
-               crc = crc32_table[(crc ^ *((char *)buf)) & 0xff] ^ (crc >> 8);
-       }
-       return crc ^ 0xffffffff;
+       return 0xffffffff ^ crc32_block_endian0(0xffffffff, buf, len, global_crc32_table);
 }
 
 static void
@@ -160,8 +153,8 @@ check_gpt_label(void)
                return 0;
        }
 
-       if (!crc32_table) {
-               crc32_table = crc32_filltable(NULL, 0);
+       if (!global_crc32_table) {
+               global_crc32_table = crc32_filltable(NULL, 0);
        }
 
        crc = SWAP_LE32(gpt_hdr->hdr_crc32);