File Coverage

File:Util.xs
Coverage:100.0%

linestmtbranpathcondsubtimecode
1/* This file is part of the Scalar::Vec::Util Perl module.
2 * See http://search.cpan.org/dist/Scalar-Vec-Util/ */
3
4#define PERL_NO_GET_CONTEXT
5#include "EXTERN.h"
6#include "perl.h"
7#include "XSUB.h"
8
9#define __PACKAGE__ "Scalar::Vec::Util"
10#define __PACKAGE_LEN__ (sizeof(__PACKAGE__)-1)
11
12#include "bitvect.h"
13
14
78171
STATIC void svu_validate_uv(pTHX_ SV *sv, size_t *offset, const char *desc) {
15#define svu_validate_uv(S, O, D) svu_validate_uv(aTHX_ (S), (O), (D))
16 IV i;
17
18
156331
 if (SvOK(sv) && SvIOK(sv)) {
19
78165
  if (SvIsUV(sv))
20
4
   *offset = SvUVX(sv);
21  else {
22
78161
   i = SvIVX(sv);
23
78161
   if (i < 0)
24
5
    goto fail;
25
78156
   *offset = i;
26  }
27 } else {
28
6
  i = SvIV(sv);
29
6
  if (i < 0)
30
3
   goto fail;
31
3
  *offset = i;
32 }
33
34 return;
35
36
8
fail:
37
8
 *offset = 0;
38
8
 croak("Invalid negative %s", desc ? desc : "integer");
39}
40
41/* --- XS ------------------------------------------------------------------ */
42
43MODULE = Scalar::Vec::Util PACKAGE = Scalar::Vec::Util
44
45PROTOTYPES: ENABLE
46
47BOOT:
48{
49
16
 HV *stash = gv_stashpvn(__PACKAGE__, __PACKAGE_LEN__, 1);
50
16
 newCONSTSUB(stash, "SVU_PP", newSVuv(0));
51
16
 newCONSTSUB(stash, "SVU_SIZE", newSVuv(SVU_SIZE));
52}
53
54void
55vfill(SV *sv, SV *ss, SV *sl, SV *sf)
56PROTOTYPE: $$$$
57PREINIT:
58 size_t s, l, n, o;
59 char f, *v;
60CODE:
61
2754
 svu_validate_uv(sl, &l, "length");
62
2753
 if (!l)
63
3
  XSRETURN(0);
64
2750
 svu_validate_uv(ss, &s, "offset");
65
2749
 f = SvTRUE(sf);
66
2749
 SvUPGRADE(sv, SVt_PV);
67
68
2749
 n = BV_SIZE(s + l);
69
2749
 o = SvLEN(sv);
70
2749
 if (n > o) {
71
11
  v = SvGROW(sv, n);
72
11
  Zero(v + o, n - o, char);
73 } else {
74
2738
  v = SvPVX(sv);
75 }
76
2749
 if (SvCUR(sv) < n)
77
206
  SvCUR_set(sv, n);
78
79
2749
 bv_fill(v, s, l, f);
80
81
2749
 XSRETURN(0);
82
83void
84vcopy(SV *sf, SV *sfs, SV *st, SV *sts, SV *sl)
85PROTOTYPE: $$$$$
86PREINIT:
87
22508
 size_t fs, ts, l, lf = 0, n, o;
88 char *t, *f;
89CODE:
90
22508
 svu_validate_uv(sl, &l, "length");
91
22507
 if (!l)
92
10
  XSRETURN(0);
93
22497
 svu_validate_uv(sfs, &fs, "offset");
94
22496
 svu_validate_uv(sts, &ts, "offset");
95
22495
 SvUPGRADE(sf, SVt_PV);
96
22495
 SvUPGRADE(st, SVt_PV);
97
98
22495
 n = BV_SIZE(ts + l);
99
22495
 o = SvLEN(st);
100
22495
 if (n > o) {
101
13
  t = SvGROW(st, n);
102
13
  Zero(t + o, n - o, char);
103 } else {
104
22482
  t = SvPVX(st);
105 }
106
22495
 if (SvCUR(st) < n)
107
5889
  SvCUR_set(st, n);
108
22495
 f = SvPVX(sf); /* We do it there in case st == sf. */
109
110
22495
 n = BV_SIZE(fs + l);
111
22495
 o = SvLEN(sf);
112
22495
 if (n > o) {
113
1
  lf = fs + l - o * CHAR_BIT;
114
1
  l = o * CHAR_BIT - fs;
115 }
116
117
22495
 if (f == t) {
118
11323
  bv_move(f, ts, fs, l);
119 } else {
120
11172
  bv_copy(t, ts, f, fs, l);
121 }
122
123
22495
 if (lf) {
124
1
  bv_fill(t, ts + l, lf, 0);
125 }
126
127
22495
 XSRETURN(0);
128
129SV *
130veq(SV *sv1, SV *ss1, SV *sv2, SV *ss2, SV *sl)
131PROTOTYPE: $$$$$
132PREINIT:
133 size_t s1, s2, l, o, n;
134 char *v1, *v2;
135CODE:
136
1729
 svu_validate_uv(sl, &l, "length");
137
1728
 if (!l)
138
9
  XSRETURN_YES;
139
1719
 svu_validate_uv(ss1, &s1, "offset");
140
1718
 svu_validate_uv(ss2, &s2, "offset");
141
1717
 SvUPGRADE(sv1, SVt_PV);
142
1717
 SvUPGRADE(sv2, SVt_PV);
143
144
1717
 n = BV_SIZE(s1 + l);
145
1717
 o = SvLEN(sv1);
146
1717
 if (n > o) {
147
1
  l = o * CHAR_BIT - s1;
148 }
149
150
1717
 n = BV_SIZE(s2 + l);
151
1717
 o = SvLEN(sv2);
152
1717
 if (n > o) {
153
1
  l = o * CHAR_BIT - s2;
154 }
155
156
1717
 v1 = SvPVX(sv1);
157
1717
 v2 = SvPVX(sv2);
158
159
1717
 RETVAL = newSVuv(bv_eq(v1, s1, v2, s2, l));
160OUTPUT:
161 RETVAL