File Coverage

CRC.xs
Criterion Covered Total %
statement 49 68 72.0
branch 33 56 58.9
condition n/a
subroutine n/a
pod n/a
total 82 124 66.1


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT
2             #include "EXTERN.h"
3             #include "perl.h"
4             #include "XSUB.h"
5              
6             #ifndef NVTYPE
7             # if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE)
8             # define NVTYPE long double
9             # else
10             # define NVTYPE double
11             # endif
12             typedef NVTYPE NV;
13             #endif
14              
15             #ifndef newSVuv
16             # define newSVuv(uv) (uv > ((~((UV)0))>>1) ? newSVnv((NV)uv) : newSViv((IV)uv))
17             #endif
18              
19             #ifndef aTHX_
20             # define aTHX_
21             #endif
22              
23             #ifndef SvGETMAGIC
24             # define SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END
25             #endif
26              
27             #define TABSIZE 256
28              
29 29           static UV reflect(UV in, int width)
30             {
31             int i;
32 29           UV out = 0;
33              
34 576 100         for (i = width; in && i; i--, in >>= 1)
    50          
35 547           out = (out << 1) | (in & 1);
36              
37 29           return out << i;
38             }
39              
40             MODULE = Digest::CRC PACKAGE = Digest::CRC
41              
42             PROTOTYPES: ENABLE
43              
44             UV
45             _reflect(in, width)
46             UV in
47             IV width
48              
49             CODE:
50 0           RETVAL = reflect(in, width);
51              
52             OUTPUT:
53             RETVAL
54              
55             SV *
56             _tabinit(width, poly, ref)
57             IV width
58             UV poly
59             IV ref
60              
61             PREINIT:
62             UV *tab;
63             UV mask, t, r, i;
64             int j, wm8;
65              
66             CODE:
67 30 100         if (ref)
68 14           poly = reflect(poly, width);
69              
70 30           mask = ((UV)1)<<(width-1);
71 30           mask = mask + (mask-1);
72              
73 30           i = TABSIZE*sizeof(UV);
74 30           RETVAL = newSV(i);
75 30           SvPOK_only(RETVAL);
76 30           SvCUR_set(RETVAL, i);
77 30           tab = (UV *) SvPVX(RETVAL);
78              
79 30 100         if (!ref) {
80 16           t = ((UV)1) << (width - 1);
81 16           wm8 = width - 8;
82             }
83              
84 7710 100         for (i = 0; i < TABSIZE; i++) {
85 7680 100         if (ref) {
86 3584           r = i;
87 32256 100         for (j = 0; j < 8; j++)
88 28672 100         if (r & 1)
89 14336           r = (r >> 1) ^ poly;
90             else
91 14336           r >>= 1;
92             }
93             else {
94 4096           r = i << (width - 8);
95 36864 100         for (j = 0; j < 8; j++)
96 32768 100         if (r & t)
97 16384           r = (r << 1) ^ poly;
98             else
99 16384           r <<= 1;
100             }
101 7680           tab[i] = r & mask;
102             }
103              
104             OUTPUT:
105             RETVAL
106              
107             SV *
108             _crc(message, width, init, xorout, refin, refout, cont, table)
109             SV *message
110             IV width
111             UV init
112             UV xorout
113             IV refin
114             IV refout
115             IV cont
116             SV *table
117              
118             PREINIT:
119             UV crc, mask, *tab;
120             STRLEN len;
121             const char *msg, *end;
122              
123             CODE:
124 31 50         SvGETMAGIC(message);
    0          
125              
126 31 50         msg = SvPV(message, len);
127 31           end = msg + len;
128 31           mask = ((UV)1)<<(width-1);
129 31           mask = mask + (mask-1);
130 31           tab = (UV *) SvPVX(table);
131              
132 31 100         crc = refin ? reflect(init, width) : init;
133 31 100         if (cont) {
134 1           crc = (init ^ xorout) & mask;
135 1 50         if (refout ^ refin)
136 0           crc = reflect(crc, width);
137             }
138              
139 31 100         if (refin) {
140 4302 100         while (msg < end)
141 4287           crc = (crc >> 8) ^ tab[(crc ^ *msg++) & 0xFF];
142             }
143             else {
144 16           int wm8 = width - 8;
145 4148 100         while (msg < end)
146 4132           crc = (crc << 8) ^ tab[((crc >> wm8) ^ *msg++) & 0xFF];
147             }
148              
149 31 50         if (refout ^ refin)
150 0           crc = reflect(crc, width);
151              
152 31           crc = (crc ^ xorout) & mask;
153              
154 31           RETVAL = newSVuv(crc);
155              
156             OUTPUT:
157             RETVAL
158              
159             SV *
160             _crc64(message, crc=0)
161             SV * message
162             UV crc
163              
164             PREINIT:
165 0           unsigned long long poly64rev = 0xd800000000000000ULL;
166             unsigned long long part;
167             int i, j;
168             static int init = 0;
169             static unsigned long long CRCTable[256];
170             STRLEN len;
171             const char *msg, *end;
172              
173             CODE:
174 0 0         SvGETMAGIC(message);
    0          
175 0 0         msg = SvPV(message, len);
176 0           end = msg + len;
177              
178 0 0         if (!init) {
179 0           init = 1;
180              
181 0 0         for (i = 0; i < 256; i++) {
182 0           part = i;
183 0 0         for (j = 0; j < 8; j++) {
184 0 0         if (part & 1)
185 0           part = (part >> 1) ^ poly64rev;
186             else
187 0           part >>= 1;
188             }
189 0           CRCTable[i] = part;
190             }
191             }
192 0 0         while (msg < end)
193 0           crc = CRCTable[(crc ^ *msg++) & 0xff] ^ (crc >> 8);
194              
195 0           RETVAL = newSVuv(crc);
196              
197             OUTPUT:
198             RETVAL
199