1 /* This file is part of the Scalar::Vec::Util Perl module.
2 * See http://search.cpan.org/dist/Scalar-Vec-Util/ */
4 #define PERL_NO_GET_CONTEXT
9 #define __PACKAGE__ "Scalar::Vec::Util"
10 #define __PACKAGE_LEN__ (sizeof(__PACKAGE__)-1)
14 STATIC size_t svu_validate_uv(pTHX_ SV *sv, const char *desc) {
15 #define svu_validate_uv(S, D) svu_validate_uv(aTHX_ (S), (D))
18 if (SvOK(sv) && SvIOK(sv)) {
32 croak("Invalid negative %s", desc ? desc : "integer");
36 STATIC char *svu_prepare_sv(pTHX_ SV *sv, size_t s, size_t l) {
37 #define svu_prepare_sv(S, I, L) svu_prepare_sv(aTHX_ (S), (I), (L))
39 size_t n = s + l, i, js, jz, k, z;
42 SvUPGRADE(sv, SVt_PV);
44 p = SvGROW(sv, BV_SIZE(n));
47 js = (s / BITS(BV_UNIT)) * sizeof(BV_UNIT);
48 k = js + sizeof(BV_UNIT);
49 for (i = c < js ? js : c; i < k; ++i)
52 jz = ((s + l - 1) / BITS(BV_UNIT)) * sizeof(BV_UNIT);
54 k = jz + sizeof(BV_UNIT);
55 for (i = c < jz ? jz : c; i < k; ++i)
59 z = 1 + ((s + l - 1) / CHAR_BIT);
66 /* --- XS ------------------------------------------------------------------ */
68 MODULE = Scalar::Vec::Util PACKAGE = Scalar::Vec::Util
74 HV *stash = gv_stashpvn(__PACKAGE__, __PACKAGE_LEN__, 1);
75 newCONSTSUB(stash, "SVU_PP", newSVuv(0));
76 newCONSTSUB(stash, "SVU_SIZE", newSVuv(SVU_SIZE));
80 vfill(SV *sv, SV *ss, SV *sl, SV *sf)
86 l = svu_validate_uv(sl, "length");
89 s = svu_validate_uv(ss, "offset");
90 v = svu_prepare_sv(sv, s, l);
98 vcopy(SV *sf, SV *sfs, SV *st, SV *sts, SV *sl)
101 size_t fs, ts, l, e, lf, cf;
104 l = svu_validate_uv(sl, "length");
107 fs = svu_validate_uv(sfs, "offset");
108 ts = svu_validate_uv(sts, "offset");
110 SvUPGRADE(sf, SVt_PV);
111 vt = svu_prepare_sv(st, ts, l);
113 /* We fetch vf after upgrading st in case st == sf. */
115 cf = SvCUR(sf) * CHAR_BIT;
117 e = lf > cf ? lf - cf : 0;
118 l = l > e ? l - e : 0;
122 bv_move(vf, ts, fs, l);
124 bv_copy(vt, ts, vf, fs, l);
128 bv_fill(vt, ts + l, e, 0);
133 veq(SV *sv1, SV *ss1, SV *sv2, SV *ss2, SV *sl)
136 size_t s1, s2, l, l1, l2, c1, c2, e1, e2, e;
140 l = svu_validate_uv(sl, "length");
143 s1 = svu_validate_uv(ss1, "offset");
144 s2 = svu_validate_uv(ss2, "offset");
146 SvUPGRADE(sv1, SVt_PV);
147 SvUPGRADE(sv2, SVt_PV);
150 c1 = SvCUR(sv1) * CHAR_BIT;
151 c2 = SvCUR(sv2) * CHAR_BIT;
156 e1 = l1 > c1 ? l1 - c1 : 0;
157 e2 = l2 > c2 ? l2 - c2 : 0;
158 e = e1 > e2 ? e1 : e2;
163 res = bv_eq(v1, s1, v2, s2, p);
167 /* Bit vectors are equal up to p < l */
174 /* l <= max(e1, e2), at least one of the vectors is completely out of bounds */
175 e = e1 < e2 ? e1 : e2;
180 res = bv_zero(v1, s1, q);
182 res = bv_zero(v2, s2, q);
186 ST(0) = res ? &PL_sv_yes : &PL_sv_no;