| File: | Util.xs |
| Coverage: | 100.0% |
| line | stmt | bran | path | cond | sub | time | code |
|---|---|---|---|---|---|---|---|
| 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 | |||||||
| 43 | MODULE = Scalar::Vec::Util PACKAGE = Scalar::Vec::Util | ||||||
| 44 | |||||||
| 45 | PROTOTYPES: ENABLE | ||||||
| 46 | |||||||
| 47 | BOOT: | ||||||
| 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 | |||||||
| 54 | void | ||||||
| 55 | vfill(SV *sv, SV *ss, SV *sl, SV *sf) | ||||||
| 56 | PROTOTYPE: $$$$ | ||||||
| 57 | PREINIT: | ||||||
| 58 | size_t s, l, n, o; | ||||||
| 59 | char f, *v; | ||||||
| 60 | CODE: | ||||||
| 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 | |||||||
| 83 | void | ||||||
| 84 | vcopy(SV *sf, SV *sfs, SV *st, SV *sts, SV *sl) | ||||||
| 85 | PROTOTYPE: $$$$$ | ||||||
| 86 | PREINIT: | ||||||
| 87 | 22508 | size_t fs, ts, l, lf = 0, n, o; | |||||
| 88 | char *t, *f; | ||||||
| 89 | CODE: | ||||||
| 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 | |||||||
| 129 | SV * | ||||||
| 130 | veq(SV *sv1, SV *ss1, SV *sv2, SV *ss2, SV *sl) | ||||||
| 131 | PROTOTYPE: $$$$$ | ||||||
| 132 | PREINIT: | ||||||
| 133 | size_t s1, s2, l, o, n; | ||||||
| 134 | char *v1, *v2; | ||||||
| 135 | CODE: | ||||||
| 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)); | |||||
| 160 | OUTPUT: | ||||||
| 161 | RETVAL | ||||||