File Coverage

lib/Bijection/XS.xs
Criterion Covered Total %
statement 40 41 97.5
branch 13 14 92.8
condition n/a
subroutine n/a
pod n/a
total 53 55 96.3


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT // we'll define thread context if necessary (faster)
2             #include "EXTERN.h" // globals/constant import locations
3             #include "perl.h" // Perl symbols, structures and constants definition
4             #include "XSUB.h" // xsubpp functions and macros
5             #include
6              
7             char * ALPHA[256];
8             int INDEX[256];
9             int OFFSET;
10             int COUNT;
11              
12 5002           void reverse(char *s) {
13 5002           size_t len = strlen(s);
14 5002           char *a = s;
15 5002           char *b = &s[(int)len - 1];
16             char tmp;
17 10006 100         for (; a < b; ++a, --b) {
18 5004           tmp = *a;
19 5004           *a = *b;
20 5004           *b = tmp;
21             }
22 5002           }
23              
24 5002           static char * _biject (int id) {
25             dTHX;
26 5002           id = id + OFFSET;
27 5002           char * outs = (char*) calloc(100, sizeof(char*));;
28 17359 100         while (id > 0) {
29 12357           strncat(outs, ALPHA[id % COUNT], 1);
30 12357           id = floor(id / COUNT);
31             }
32 5002           reverse(outs);
33 5002           return outs;
34             }
35              
36 5001           static int _inverse (char * id) {
37             dTHX;
38 5001           int out = 0, i = 0;
39 17352 100         for (i = 0; i < strlen(id); i++) {
40 12351           out = out * COUNT + INDEX[(int)id[i]];
41             }
42 5001           return out - OFFSET;
43             }
44              
45              
46             MODULE = Bijection::XS PACKAGE = Bijection::XS
47             PROTOTYPES: ENABLE
48              
49             SV *
50             bijection_set(...)
51             CODE:
52 5           AV * args = av_make(items, MARK+1);
53 5           SV * first = *av_fetch(args, 0, 0);
54 5           int i = 0;
55            
56 5 100         if (SvTYPE(first) == SVt_IV && SvIV(first) > 0) {
    50          
57 1           OFFSET = SvIV(first);
58 1           av_shift(args);
59             } else {
60 4           OFFSET = av_len(args) + 1;
61             }
62              
63 5           COUNT = av_len(args) + 1;
64 265 100         for (i = 0; i < COUNT; i++) {
65             STRLEN retlen;
66 260           char * key = SvPV(*av_fetch(args, i, 0), retlen);
67 260           ALPHA[i] = key;
68 260           INDEX[(int)key[0]] = i;
69             }
70              
71 5           RETVAL = newSViv(OFFSET);
72             OUTPUT:
73             RETVAL
74              
75             void
76             offset_set(offset)
77             SV * offset
78             CODE:
79 0           OFFSET = SvIV(offset);
80              
81              
82             SV *
83             biject(id)
84             SV * id
85             CODE:
86 5004 100         if (SvIV(id) < 0) {
87 2           croak("id to encode must be an integer and non-negative");
88             }
89 5002           char * str = _biject(SvIV(id));
90 5002           RETVAL = newSVpv(str, strlen(str));
91             OUTPUT:
92             RETVAL
93              
94             SV *
95             inverse(str)
96             SV * str
97             CODE:
98             STRLEN retlen;
99 5001           RETVAL = newSViv(_inverse(SvPV(str, retlen)));
100             OUTPUT:
101             RETVAL
102