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, j1, j2, k, z;
42 SvUPGRADE(sv, SVt_PV);
44 p = SvGROW(sv, BV_SIZE(n));
47 j1 = (s / BITS(BV_UNIT)) * sizeof(BV_UNIT);
48 k = j1 + sizeof(BV_UNIT);
49 for (i = c < j1 ? j1 : c; i < k; ++i)
52 j2 = ((s + l - 1) / BITS(BV_UNIT)) * sizeof(BV_UNIT);
54 k = j2 + sizeof(BV_UNIT);
55 for (i = c < j2 ? j2 : 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, lf = 0, c;
104 l = svu_validate_uv(sl, "length");
107 fs = svu_validate_uv(sfs, "offset");
108 ts = svu_validate_uv(sts, "offset");
110 t = svu_prepare_sv(st, ts, l);
112 f = SvPVX(sf); /* We do it there in case st == sf. */
114 if (c * CHAR_BIT <= fs + l && c <= SvCUR(st)) {
115 lf = fs + l - c * CHAR_BIT;
116 l = c * CHAR_BIT - fs;
120 bv_move(f, ts, fs, l);
122 bv_copy(t, ts, f, fs, l);
126 bv_fill(t, ts + l, lf, 0);
132 veq(SV *sv1, SV *ss1, SV *sv2, SV *ss2, SV *sl)
135 size_t s1, s2, l, o, n;
138 l = svu_validate_uv(sl, "length");
141 s1 = svu_validate_uv(ss1, "offset");
142 s2 = svu_validate_uv(ss2, "offset");
143 SvUPGRADE(sv1, SVt_PV);
144 SvUPGRADE(sv2, SVt_PV);
149 l = o * CHAR_BIT - s1;
155 l = o * CHAR_BIT - s2;
161 RETVAL = newSVuv(bv_eq(v1, s1, v2, s2, l));