]> mj.ucw.cz Git - libucw.git/blobdiff - ucw/crc.c
Config: Added support for terabyte values, for example "123T".
[libucw.git] / ucw / crc.c
index 2c03ccdb39ac1236d4d7ba910e5dba3ff4e147f5..070a261642db4df11a994f0361165860c5af10b5 100644 (file)
--- a/ucw/crc.c
+++ b/ucw/crc.c
@@ -20,7 +20,7 @@
 #include <ucw/crc.h>
 #include <ucw/crc-tables.h>
 
-static void crc32_update_by1(crc32_context *ctx, const byte *buf, uns len)
+static void crc32_update_by1(crc32_context *ctx, const byte *buf, uint len)
 {
   u32 crc = ctx->state;
   while (len--)
@@ -28,11 +28,16 @@ static void crc32_update_by1(crc32_context *ctx, const byte *buf, uns len)
   ctx->state = crc;
 }
 
-static void crc32_update_by4(crc32_context *ctx, const byte *buf, uns len)
+static void crc32_update_by4(crc32_context *ctx, const byte *buf, uint len)
 {
-  uns init_bytes, words;
+  uint init_bytes, words;
   u32 crc = ctx->state;
-  u32 term1, term2, *buf32;
+  u32 term1, term2;
+  const u32 *buf32;
+
+  // Special case
+  if (len < 4)
+    goto small;
 
   // Align start address to a multiple of 4 bytes
   init_bytes = ((uintptr_t) buf) & 3;
@@ -47,7 +52,7 @@ static void crc32_update_by4(crc32_context *ctx, const byte *buf, uns len)
   // Process 4 bytes at a time
   words = len/4;
   len -= 4*words;
-  buf32 = (u32 *) buf;
+  buf32 = (const u32 *) buf;
   while (words--)
     {
       crc ^= *buf32++;
@@ -59,18 +64,24 @@ static void crc32_update_by4(crc32_context *ctx, const byte *buf, uns len)
     }
 
   // Process remaining up to 7 bytes
-  buf = (byte *) buf32;
+  buf = (const byte *) buf32;
+small:
   while (len--)
     crc = crc_tableil8_o32[(crc ^ *buf++) & 0x000000FF] ^ (crc >> 8);
 
   ctx->state = crc;
 }
 
-static void crc32_update_by8(crc32_context *ctx, const byte *buf, uns len)
+static void crc32_update_by8(crc32_context *ctx, const byte *buf, uint len)
 {
-  uns init_bytes, quads;
+  uint init_bytes, quads;
   u32 crc = ctx->state;
-  u32 term1, term2, *buf32;
+  u32 term1, term2;
+  const u32 *buf32;
+
+  // Special case
+  if (len < 8)
+    goto small;
 
   // Align start address to a multiple of 8 bytes
   init_bytes = ((uintptr_t) buf) & 7;
@@ -85,7 +96,7 @@ static void crc32_update_by8(crc32_context *ctx, const byte *buf, uns len)
   // Process 8 bytes at a time
   quads = len/8;
   len -= 8*quads;
-  buf32 = (u32 *) buf;
+  buf32 = (const u32 *) buf;
   while (quads--)
     {
       crc ^= *buf32++;
@@ -107,7 +118,8 @@ static void crc32_update_by8(crc32_context *ctx, const byte *buf, uns len)
     }
 
   // Process remaining up to 7 bytes
-  buf = (byte *) buf32;
+  buf = (const byte *) buf32;
+small:
   while (len--)
     crc = crc_tableil8_o32[(crc ^ *buf++) & 0x000000FF] ^ (crc >> 8);
 
@@ -115,7 +127,7 @@ static void crc32_update_by8(crc32_context *ctx, const byte *buf, uns len)
 }
 
 void
-crc32_init(crc32_context *ctx, uns crc_mode)
+crc32_init(crc32_context *ctx, uint crc_mode)
 {
   ctx->state = 0xffffffff;
   switch (crc_mode)
@@ -134,6 +146,15 @@ crc32_init(crc32_context *ctx, uns crc_mode)
     }
 }
 
+u32
+crc32_hash_buffer(const byte *buf, uint len)
+{
+  crc32_context ctx;
+  crc32_init(&ctx, CRC_MODE_DEFAULT);
+  crc32_update(&ctx, buf, len);
+  return crc32_final(&ctx);
+}
+
 #ifdef TEST
 
 #include <stdio.h>
@@ -143,28 +164,28 @@ int main(int argc, char **argv)
 {
   if (argc != 5)
     die("Usage: crc-t <alg> <len> <block> <iters>");
-  uns alg = atoi(argv[1]);
-  uns len = atoi(argv[2]);
-  uns block = atoi(argv[3]);
-  uns iters = atoi(argv[4]);
+  uint alg = atoi(argv[1]);
+  uint len = atoi(argv[2]);
+  uint block = atoi(argv[3]);
+  uint iters = atoi(argv[4]);
 
   byte *buf = xmalloc(len);
-  for (uns i=0; i<len; i++)
+  for (uint i=0; i<len; i++)
     buf[i] = i ^ (i >> 5) ^ (i >> 11);
 
-  for (uns i=0; i<iters; i++)
+  for (uint i=0; i<iters; i++)
     {
       crc32_context ctx;
-      uns modes[] = { CRC_MODE_DEFAULT, CRC_MODE_SMALL, CRC_MODE_BIG };
+      uint modes[] = { CRC_MODE_DEFAULT, CRC_MODE_SMALL, CRC_MODE_BIG };
       ASSERT(alg < ARRAY_SIZE(modes));
       crc32_init(&ctx, modes[alg]);
-      for (uns p=0; p<len;)
+      for (uint p=0; p<len;)
        {
-         uns l = MIN(len-p, block);
+         uint l = MIN(len-p, block);
          crc32_update(&ctx, buf+p, l);
          p += l;
        }
-      uns crc = crc32_final(&ctx);
+      uint crc = crc32_final(&ctx);
       if (!i)
        printf("%08x\n", crc);
     }