X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FScalar-Vec-Util.git;a=blobdiff_plain;f=Util.xs;h=86a21cae21f8f92668960c29cb619330851b249a;hp=6733972275805f09ed91925b6899ffa744afa19e;hb=4dc1aa8932c595136b763a34207e4e9ee683dc53;hpb=2bade59206c8f2bd2ed64e1faa8b10cc9109b734 diff --git a/Util.xs b/Util.xs index 6733972..86a21ca 100644 --- a/Util.xs +++ b/Util.xs @@ -98,8 +98,8 @@ void vcopy(SV *sf, SV *sfs, SV *st, SV *sts, SV *sl) PROTOTYPE: $$$$$ PREINIT: - size_t fs, ts, l, lf = 0, c; - char *t, *f; + size_t fs, ts, l, e, lf, cf; + char *vt, *vf; CODE: l = svu_validate_uv(sl, "length"); if (!l) @@ -107,24 +107,25 @@ CODE: fs = svu_validate_uv(sfs, "offset"); ts = svu_validate_uv(sts, "offset"); - t = svu_prepare_sv(st, ts, l); - - f = SvPVX(sf); /* We do it there in case st == sf. */ - c = SvCUR(sf); - if (c * CHAR_BIT <= fs + l && c <= SvCUR(st)) { - lf = fs + l - c * CHAR_BIT; - l = c * CHAR_BIT - fs; + SvUPGRADE(sf, SVt_PV); + vt = svu_prepare_sv(st, ts, l); + + /* We fetch vf after upgrading st in case st == sf. */ + vf = SvPVX(sf); + cf = SvCUR(sf) * CHAR_BIT; + lf = fs + l; + e = lf > cf ? lf - cf : 0; + l = l > e ? l - e : 0; + + if (l) { + if (vf == vt) + bv_move(vf, ts, fs, l); + else + bv_copy(vt, ts, vf, fs, l); } - if (f == t) { - bv_move(f, ts, fs, l); - } else { - bv_copy(t, ts, f, fs, l); - } - - if (lf) { - bv_fill(t, ts + l, lf, 0); - } + if (e) + bv_fill(vt, ts + l, e, 0); XSRETURN(0);