LCOV - code coverage report
Current view: top level - utils - adler32.cc (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 31 44 70.5 %
Date: 2015-01-12 15:17:13 Functions: 1 2 50.0 %
Branches: 16 24 66.7 %

           Branch data     Line data    Source code
       1                 :            : /* adler32.c -- compute the Adler-32 checksum of a data stream
       2                 :            :  * Copyright (C) 1995-2003 Mark Adler
       3                 :            :  * For conditions of distribution and use, see copyright notice in zlib.h
       4                 :            :  */
       5                 :            : 
       6                 :            : /* @(#) $Id: adler32.c,v 1.1.1.2 2002/03/11 21:53:23 tromey Exp $ */
       7                 :            : 
       8                 :            : /* Modified by Jung-Sang Ahn in 2014 */
       9                 :            : 
      10                 :            : #include "adler32.h"
      11                 :            : 
      12                 :            : #define BASE 65521      /* largest prime smaller than 65536 */
      13                 :            : #define NMAX 5552
      14                 :            : /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
      15                 :            : 
      16                 :            : #define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}
      17                 :            : #define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
      18                 :            : #define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
      19                 :            : #define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
      20                 :            : #define DO16(buf)   DO8(buf,0); DO8(buf,8);
      21                 :            : 
      22                 :            : /* use NO_DIVIDE if your processor does not do division in hardware --
      23                 :            :    try it both ways to see which is faster */
      24                 :            : #ifdef NO_DIVIDE
      25                 :            : /* note that this assumes BASE is 65521, where 65536 % 65521 == 15
      26                 :            :    (thank you to John Reiser for pointing this out) */
      27                 :            : #  define CHOP(a) \
      28                 :            :     do { \
      29                 :            :         unsigned long tmp = a >> 16; \
      30                 :            :         a &= 0xffffUL; \
      31                 :            :         a += (tmp << 4) - tmp; \
      32                 :            :     } while (0)
      33                 :            : #  define MOD28(a) \
      34                 :            :     do { \
      35                 :            :         CHOP(a); \
      36                 :            :         if (a >= BASE) a -= BASE; \
      37                 :            :     } while (0)
      38                 :            : #  define MOD(a) \
      39                 :            :     do { \
      40                 :            :         CHOP(a); \
      41                 :            :         MOD28(a); \
      42                 :            :     } while (0)
      43                 :            : #  define MOD63(a) \
      44                 :            :     do { /* this assumes a is not negative */ \
      45                 :            :         z_off64_t tmp = a >> 32; \
      46                 :            :         a &= 0xffffffffL; \
      47                 :            :         a += (tmp << 8) - (tmp << 5) + tmp; \
      48                 :            :         tmp = a >> 16; \
      49                 :            :         a &= 0xffffL; \
      50                 :            :         a += (tmp << 4) - tmp; \
      51                 :            :         tmp = a >> 16; \
      52                 :            :         a &= 0xffffL; \
      53                 :            :         a += (tmp << 4) - tmp; \
      54                 :            :         if (a >= BASE) a -= BASE; \
      55                 :            :     } while (0)
      56                 :            : #else
      57                 :            : #  define MOD(a) a %= BASE
      58                 :            : #  define MOD28(a) a %= BASE
      59                 :            : #  define MOD63(a) a %= BASE
      60                 :            : #endif
      61                 :            : 
      62                 :            : /* ========================================================================= */
      63                 :          4 : uint32_t adler32(uint32_t adler, uint8_t *buf, size_t len)
      64                 :            : {
      65                 :            :     unsigned long sum2;
      66                 :            :     unsigned n;
      67                 :            : 
      68                 :            :     /* split Adler-32 into component sums */
      69                 :          4 :     sum2 = (adler >> 16) & 0xffff;
      70                 :          4 :     adler &= 0xffff;
      71                 :            : 
      72                 :            :     /* in case user likes doing a byte at a time, keep it fast */
      73         [ -  + ]:          4 :     if (len == 1) {
      74                 :          0 :         adler += buf[0];
      75         [ #  # ]:          0 :         if (adler >= BASE)
      76                 :          0 :             adler -= BASE;
      77                 :          0 :         sum2 += adler;
      78         [ #  # ]:          0 :         if (sum2 >= BASE)
      79                 :          0 :             sum2 -= BASE;
      80                 :          0 :         return adler | (sum2 << 16);
      81                 :            :     }
      82                 :            : 
      83                 :            :     /* initial Adler-32 value (deferred check for len == 1 speed) */
      84         [ -  + ]:          4 :     if (buf == NULL)
      85                 :          0 :         return 1L;
      86                 :            : 
      87                 :            :     /* in case short lengths are provided, keep it somewhat fast */
      88         [ +  + ]:          4 :     if (len < 16) {
      89         [ +  + ]:         19 :         while (len--) {
      90                 :         16 :             adler += *buf++;
      91                 :         16 :             sum2 += adler;
      92                 :            :         }
      93         [ -  + ]:          3 :         if (adler >= BASE)
      94                 :          0 :             adler -= BASE;
      95                 :          3 :         MOD28(sum2);            /* only added so many BASE's */
      96                 :          3 :         return adler | (sum2 << 16);
      97                 :            :     }
      98                 :            : 
      99                 :            :     /* do length NMAX blocks -- requires just one modulo operation */
     100         [ +  + ]:     193398 :     while (len >= NMAX) {
     101                 :     193397 :         len -= NMAX;
     102                 :     193397 :         n = NMAX / 16;          /* NMAX is divisible by 16 */
     103         [ +  + ]:   67108759 :         do {
     104                 :   67108759 :             DO16(buf);          /* 16 sums unrolled */
     105                 :   67108759 :             buf += 16;
     106                 :            :         } while (--n);
     107                 :     193397 :         MOD(adler);
     108                 :     193397 :         MOD(sum2);
     109                 :            :     }
     110                 :            : 
     111                 :            :     /* do remaining bytes (less than NMAX, still just one modulo) */
     112         [ +  - ]:          1 :     if (len) {                  /* avoid modulos if none remaining */
     113         [ +  + ]:        106 :         while (len >= 16) {
     114                 :        105 :             len -= 16;
     115                 :        105 :             DO16(buf);
     116                 :        105 :             buf += 16;
     117                 :            :         }
     118         [ +  + ]:          8 :         while (len--) {
     119                 :          7 :             adler += *buf++;
     120                 :          7 :             sum2 += adler;
     121                 :            :         }
     122                 :          1 :         MOD(adler);
     123                 :          1 :         MOD(sum2);
     124                 :            :     }
     125                 :            : 
     126                 :            :     /* return recombined sums */
     127                 :          4 :     return adler | (sum2 << 16);
     128                 :            : }
     129                 :            : 
     130                 :            : #define MIN(a,b) (((a)<(b))?(a):(b))
     131                 :          0 : uint32_t adler32_last8(uint32_t adler, uint8_t *buf, size_t len)
     132                 :            : {
     133                 :          0 :     size_t min = MIN(len, 8);
     134                 :          0 :     uint8_t *src = buf + (len-min);
     135                 :            : #ifdef _ALIGN_MEM_ACCESS
     136                 :            :     uint64_t temp; // aligned
     137                 :            :     memcpy(&temp, src, min);
     138                 :            :     src = &temp;
     139                 :            : #endif
     140                 :          0 :     return adler32(adler, src, min);
     141                 :            : }
     142                 :            : 

Generated by: LCOV version 1.11