File Coverage

xs/record_opaque.c
Criterion Covered Total %
statement 61 67 91.0
branch 60 96 62.5
condition n/a
subroutine n/a
pod n/a
total 121 163 74.2


line stmt bran cond sub pod time code
1             #include "EXTERN.h"
2             #include "perl.h"
3             #include "XSUB.h"
4             #include "ppport.h"
5             #include "ffi_platypus.h"
6             #include "ffi_platypus_guts.h"
7              
8 16           XS(ffi_pl_record_accessor_opaque)
9             {
10             ffi_pl_record_member *member;
11             SV *self;
12             SV *arg;
13             char *ptr1;
14             void **ptr2;
15              
16 16           dVAR; dXSARGS;
17              
18 16 50         if(items == 0)
19 0           croak("This is a method, you must provide at least the object");
20              
21 16           member = (ffi_pl_record_member*) CvXSUBANY(cv).any_ptr;
22              
23 16           self = ST(0);
24 16 50         if(SvROK(self))
25 16           self = SvRV(self);
26              
27 16 50         if(!SvOK(self))
    0          
    0          
28 0           croak("Null record error");
29              
30 16 50         ptr1 = (char*) SvPV_nolen(self);
31 16           ptr2 = (void**) &ptr1[member->offset];
32              
33 16 100         if(items > 1)
34             {
35 6 100         if(SvREADONLY(self))
36             {
37 2           croak("record is read-only");
38             }
39             else
40             {
41 4           arg = ST(1);
42 4 100         *ptr2 = SvOK(arg) ? INT2PTR(void*, SvIV(arg)) : NULL;
    50          
    50          
    50          
43             }
44             }
45              
46 14 50         if(GIMME_V == G_VOID)
    100          
47 4           XSRETURN_EMPTY;
48              
49 10 100         if(*ptr2 != NULL)
50 9           XSRETURN_IV( PTR2IV( *ptr2 ));
51             else
52 1           XSRETURN_EMPTY;
53             }
54              
55 27           XS(ffi_pl_record_accessor_opaque_array)
56             {
57             ffi_pl_record_member *member;
58             SV *self;
59             SV *arg;
60             SV **item;
61             AV *av;
62             char *ptr1;
63             void **ptr2;
64             int i;
65              
66 27           dVAR; dXSARGS;
67              
68 27 50         if(items == 0)
69 0           croak("This is a method, you must provide at least the object");
70              
71 27           member = (ffi_pl_record_member*) CvXSUBANY(cv).any_ptr;
72              
73 27           self = ST(0);
74 27 50         if(SvROK(self))
75 27           self = SvRV(self);
76              
77 27 50         if(!SvOK(self))
    0          
    0          
78 0           croak("Null record error");
79              
80 27 50         ptr1 = (char*) SvPV_nolen(self);
81 27           ptr2 = (void**) &ptr1[member->offset];
82              
83 27 100         if(items > 1 && SvREADONLY(self))
    100          
84             {
85 4           croak("record is read-only");
86             }
87              
88 23 100         if(items > 2)
89             {
90 2 50         i = SvIV(ST(1));
91 2 50         if(i >= 0 && i < member->count)
    50          
92             {
93 2           arg = ST(2);
94 2 100         ptr2[i] = SvOK(arg) ? INT2PTR(void*, SvIV(arg)) : NULL;
    50          
    50          
    50          
95             }
96             else
97             {
98 2           warn("illegal index %d", i);
99             }
100             }
101 21 100         else if(items > 1)
102             {
103 6           arg = ST(1);
104 9 100         if(SvROK(arg) && SvTYPE(SvRV(arg)) == SVt_PVAV)
    50          
105             {
106 3           av = (AV*) SvRV(arg);
107 10 100         for(i=0; i < member->count; i++)
108             {
109 7           item = av_fetch(av, i, 0);
110 7 50         if(item != NULL && SvOK(*item))
    100          
    50          
    50          
111             {
112 6 50         ptr2[i] = INT2PTR(void*, SvIV(*item));
113             }
114             else
115             {
116 1           ptr2[i] = NULL;
117             }
118             }
119             }
120             else
121             {
122 3 50         i = SvIV(ST(1));
123 3 50         if(i < 0 && i >= member->count)
    0          
124             {
125 0           warn("illegal index %d", i);
126 0           XSRETURN_EMPTY;
127             }
128 3 100         else if(ptr2[i] == NULL)
129             {
130 1           XSRETURN_EMPTY;
131             }
132             else
133             {
134 2           XSRETURN_IV(PTR2IV(ptr2[i]));
135             }
136             warn("passing non array reference into ffi/platypus array argument type");
137             }
138             }
139              
140 20 50         if(GIMME_V == G_VOID)
    100          
141 5           XSRETURN_EMPTY;
142              
143 15           av = newAV();
144 15           av_fill(av, member->count-1);
145 48 100         for(i=0; i < member->count; i++)
146             {
147 33 100         if(ptr2[i] != NULL)
148 31           sv_setiv(*av_fetch(av, i, 1), PTR2IV(ptr2[i]));
149             }
150 15           ST(0) = newRV_inc((SV*)av);
151 15           XSRETURN(1);
152             }