]> git.vpit.fr Git - perl/modules/Scalar-Vec-Util.git/blob - Util.xs
Improve size discovery
[perl/modules/Scalar-Vec-Util.git] / Util.xs
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 STATIC const char svu_error_invarg[] = "Invalid argument";
15
16 /* --- XS ------------------------------------------------------------------ */
17
18 MODULE = Scalar::Vec::Util              PACKAGE = Scalar::Vec::Util
19
20 PROTOTYPES: ENABLE
21
22 BOOT:
23 {
24  HV *stash = gv_stashpvn(__PACKAGE__, __PACKAGE_LEN__, 1);
25  newCONSTSUB(stash, "SVU_PP",   newSVuv(0));
26  newCONSTSUB(stash, "SVU_SIZE", newSVuv(SVU_SIZE));
27 }
28
29 void
30 vfill(SV *sv, SV *ss, SV *sl, SV *sf)
31 PREINIT:
32  size_t s, l, n, o;
33  char f, *v;
34 CODE:
35  if (!SvOK(sv) || !SvOK(ss) || !SvOK(sl) || !SvOK(sf))
36   croak(svu_error_invarg);
37
38  l = SvUV(sl);
39  if (!l)
40   XSRETURN(0);
41  s = SvUV(ss);
42  f = SvTRUE(sf);
43  SvUPGRADE(sv, SVt_PV);
44
45  n = BV_SIZE(s + l);
46  o = SvLEN(sv);
47  if (n > o) {
48   v = SvGROW(sv, n);
49   Zero(v + o, n - o, char);
50  } else {
51   v = SvPVX(sv);
52  }
53  if (SvCUR(sv) < n)
54   SvCUR_set(sv, n);
55
56  bv_fill(v, s, l, f);
57
58  XSRETURN(0);
59
60 void
61 vcopy(SV *sf, SV *sfs, SV *st, SV *sts, SV *sl)
62 PREINIT:
63  size_t fs, ts, l, lf = 0, n, o;
64  char *t, *f;
65 CODE:
66  if (!SvOK(sf) || !SvOK(sfs) || !SvOK(st) || !SvOK(sts) || !SvOK(sl))
67   croak(svu_error_invarg);
68
69  l  = SvUV(sl);
70  if (!l)
71   XSRETURN(0);
72  fs = SvUV(sfs);
73  ts = SvUV(sts);
74  SvUPGRADE(sf, SVt_PV);
75  SvUPGRADE(st, SVt_PV);
76
77  n  = BV_SIZE(ts + l);
78  o  = SvLEN(st);
79  if (n > o) {
80   t = SvGROW(st, n);
81   Zero(t + o, n - o, char);
82  } else {
83   t = SvPVX(st);
84  }
85  if (SvCUR(st) < n)
86   SvCUR_set(st, n);
87  f = SvPVX(sf); /* We do it there in case st == sf. */
88
89  n  = BV_SIZE(fs + l);
90  o  = SvLEN(sf);
91  if (n > o) {
92   lf = fs + l - o * CHAR_BIT;
93   l  = o * CHAR_BIT - fs;
94  }
95
96  if (f == t) {
97   bv_move(f, ts, fs, l);
98  } else {
99   bv_copy(t, ts, f, fs, l);
100  }
101
102  if (lf) {
103   bv_fill(t, ts + l, lf, 0);
104  }
105
106  XSRETURN(0);
107
108 SV *
109 veq(SV *sv1, SV *ss1, SV *sv2, SV *ss2, SV *sl)
110 PREINIT:
111  size_t s1, s2, l, o, n;
112  char *v1, *v2;
113 CODE:
114  if (!SvOK(sv1) || !SvOK(ss1) || !SvOK(sv2) || !SvOK(ss2) || !SvOK(sl))
115   croak(svu_error_invarg);
116
117  l  = SvUV(sl);
118  s1 = SvUV(ss1);
119  s2 = SvUV(ss2);
120  SvUPGRADE(sv1, SVt_PV);
121  SvUPGRADE(sv2, SVt_PV);
122
123  n  = BV_SIZE(s1 + l);
124  o  = SvLEN(sv1);
125  if (n > o) {
126   l = o * CHAR_BIT - s1;
127  }
128
129  n  = BV_SIZE(s2 + l);
130  o  = SvLEN(sv2);
131  if (n > o) {
132   l = o * CHAR_BIT - s2;
133  }
134
135  v1 = SvPVX(sv1);
136  v2 = SvPVX(sv2);
137
138  RETVAL = newSVuv(bv_eq(v1, s1, v2, s2, l));
139 OUTPUT:
140  RETVAL