File Coverage

XS.xs
Criterion Covered Total %
statement 57 57 100.0
branch 22 30 73.3
condition n/a
subroutine n/a
pod n/a
total 79 87 90.8


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             #define XX 255
7             #define INVALID XX
8              
9             static const char base_32[32] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
10              
11             static const unsigned char index_32[256] = {
12             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
13             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
14             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
15             XX,XX,26,27, 28,29,30,31, XX,XX,XX,XX, XX,XX,XX,XX,
16             XX, 0, 1, 2, 3 , 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
17             15,16,17,18, 19,20,21,22, 23,24,25,XX, XX,XX,XX,XX,
18             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
19             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
20             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
21             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
22             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
23             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
24             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
25             XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
26             };
27              
28             MODULE = MIME::Base32::XS PACKAGE = MIME::Base32::XS
29              
30             SV *
31             encode_base32(SV *sv)
32             PREINIT:
33             STRLEN len;
34             SSize_t size;
35             unsigned char *input;
36             unsigned char *output;
37 93           unsigned long long x = 0;
38 93           unsigned int i, z, n = 0;
39 93           char ap[5] = {0, 6, 4, 3, 1};
40              
41             CODE:
42 93 50         input = SvPV(sv, len);
43 93           size = (SSize_t)len;
44 93           len = (size * 2) + ap[size % 5];
45 93 50         RETVAL = newSV(len ? len : 1);
46 93           SvPOK_on(RETVAL);
47 93           output = SvPVX(RETVAL);
48              
49 186 100         for (i = 0; i < size; i++) {
50 186 50         for (z = 0; z < 5 && i < size; z++, i++) {
    100          
51 93           x |= input[i];
52 93           x <<= 8;
53             }
54              
55 93           x <<= (7 - z) << 3;
56              
57 93           *output++ = base_32[x >> 59];
58 93           *output++ = base_32[(x << 5) >> 59];
59 93           *output++ = base_32[(x << 10) >> 59];
60 93           *output++ = base_32[(x << 15) >> 59];
61 93           *output++ = base_32[(x << 20) >> 59];
62 93           *output++ = base_32[(x << 25) >> 59];
63 93           *output++ = base_32[(x << 30) >> 59];
64 93           *output++ = base_32[(x << 35) >> 59];
65              
66 93           --i;
67 93           n += 8;
68             }
69              
70 93           *output = '\0';
71              
72 651 100         for (i = ap[size % 5]; i; i--)
73 558           *--output = '=';
74              
75 93           SvCUR_set(RETVAL, n);
76              
77             OUTPUT:
78             RETVAL
79              
80             SV *
81             decode_base32(SV *sv)
82             PREINIT:
83             STRLEN len;
84             SSize_t size;
85             unsigned char *input;
86             char *output;
87             unsigned long long x;
88 93           unsigned int i, z, rtsize, v, n = 0;
89             unsigned char pad;
90             unsigned char t;
91 93           char lkpad[7] = {0, 4, 0, 3, 2, 0, 1};
92              
93             CODE:
94 93 50         input = SvPV(sv, len);
95 93           size = (SSize_t)len;
96              
97 651 100         for (pad = 0, i = len-1; input[i] == '='; i--) {
98 558           ++pad;
99 558           --size;
100             }
101              
102 93           len = (len * 3 / 4);
103 93 50         RETVAL = newSV(len ? len : 1);
104 93           SvPOK_on(RETVAL);
105 93           output = SvPVX(RETVAL);
106              
107 186 100         for (i = 0; i < size; i++) {
108 93 50         if (input[i] != '=') {
109 279 50         for (x = 0, z = 0; z < 8 && i < size; z++, i++) {
    100          
110 186           v = index_32[input[i]];
111 186 50         if (v != INVALID) {
112 2368 100         for (t = 0; v != t; t++);
113 186           x |= t;
114 186           x <<= 5;
115             }
116             }
117              
118 93           x <<= (19 + ((8 - z) * 5));
119 93           *output++ = x >> 56;
120 93           *output++ = (x << 8) >> 56;
121 93           *output++ = (x << 16) >> 56;
122 93           *output++ = (x << 24) >> 56;
123 93           *output++ = (x << 32) >> 56;
124 93           --i;
125             }
126             }
127              
128 93           n = (size >> 3) * 5 + lkpad[pad];
129              
130 93           output[n] = '\0';
131              
132 93           SvCUR_set(RETVAL, n);
133              
134             OUTPUT:
135             RETVAL