static char * my_sv_unchop(pTHX_ SV *sv, STRLEN size) { STRLEN len; char *pv = SvPV(sv, len); IV off = SvOOK(sv) ? SvIVX(sv) : 0; if (!size) return pv; if (off >= size) { SvLEN_set(sv, SvLEN(sv) + size); SvCUR_set(sv, len + size); SvPV_set(sv, pv - size); if (off == size) SvFLAGS(sv) &= ~SVf_OOK; else SvIV_set(sv, off - size); } else if (len + size <= off + SvLEN(sv)) { if (off) { SvLEN_set(sv, SvLEN(sv) + off); SvFLAGS(sv) &= ~SVf_OOK; } SvCUR_set(sv, len + size); SvPV_set(sv, pv - off); Move(pv, pv + size - off, len, char); } else { SV *tmp = sv_2mortal(newSV(len + size)); STRLEN tmp_len; char *tmp_pv; SvPOK_on(tmp); tmp_pv = SvPV(tmp, tmp_len); Move(pv, tmp_pv + size, len, char); SvCUR_set(tmp, size + len); sv_setsv(sv, tmp); } return SvPVX(sv); }