Change 14546 by jhi@alpha on 2002/02/04 04:41:02
Integrate perlio.
Carry on where we left off if we have to grow destination
SV during XS encode/decode
Remove debugging warning, be consistent about API fails.
Affected files ...
.... //depot/perl/ext/Encode/Encode.xs#45 integrate
Differences ...
==== //depot/perl/ext/Encode/Encode.xs#45 (text) ====
Index: perl/ext/Encode/Encode.xs
--- perl/ext/Encode/Encode.xs.~1~ Sun Feb 3 21:45:06 2002
+++ perl/ext/Encode/Encode.xs Sun Feb 3 21:45:06 2002
@@ -309,14 +309,12 @@
XPUSHs(e->enc);
SvCUR_set(e->bufsv, e->base.ptr - e->base.buf);
SvUTF8_on(e->bufsv);
-#if 0
- Perl_warn(aTHX_ "flush %_",e->bufsv);
-#endif
XPUSHs(e->bufsv);
XPUSHs(&PL_sv_yes);
PUTBACK;
- if (perl_call_method("encode", G_SCALAR) != 1)
- code = -1;
+ if (perl_call_method("encode", G_SCALAR) != 1) {
+ Perl_die(aTHX_ "panic: encode did not return a value");
+ }
SPAGAIN;
str = POPs;
PUTBACK;
@@ -359,8 +357,9 @@
XPUSHs(str);
XPUSHs(&PL_sv_yes);
PUTBACK;
- if (perl_call_method("encode", G_SCALAR) != 1)
- code = -1;
+ if (perl_call_method("encode", G_SCALAR) != 1) {
+ Perl_die(aTHX_ "panic: encode did not return a value");
+ }
SPAGAIN;
str = POPs;
PUTBACK;
@@ -479,18 +478,20 @@
{
STRLEN slen;
U8 *s = (U8 *) SvPV(src, slen);
- STRLEN tlen = slen;
+ STRLEN tlen = slen;
+ STRLEN ddone = 0;
+ STRLEN sdone = 0;
SV *dst = sv_2mortal(newSV(slen+1));
if (slen) {
U8 *d = (U8 *) SvPVX(dst);
STRLEN dlen = SvLEN(dst)-1;
int code;
while ((code = do_encode(dir, s, &slen, d, dlen, &dlen, !check))) {
- SvCUR_set(dst, dlen);
+ SvCUR_set(dst, dlen+ddone);
SvPOK_on(dst);
#if 0
- Perl_warn(aTHX_ "code=%d @ s=%d/%d d=%d",code,slen,tlen,dlen);
+ Perl_warn(aTHX_ "code=%d @ s=%d/%d/%d
+d=%d/%d/%d",code,slen,sdone,tlen,dlen,ddone,SvLEN(dst)-1);
#endif
if (code == ENCODE_FALLBACK || code == ENCODE_PARTIAL)
@@ -499,23 +500,25 @@
switch (code) {
case ENCODE_NOSPACE:
{
- STRLEN done = tlen-slen;
STRLEN need ;
- if (done) {
- need = (tlen*dlen)/done+1;
+ sdone += slen;
+ ddone += dlen;
+ if (sdone) {
+ need = (tlen*SvLEN(dst)+sdone-1)/sdone+UTF8_MAXLEN;
}
else {
- need = dlen + UTF8_MAXLEN;
+ need = SvLEN(dst) + UTF8_MAXLEN;
}
d = (U8 *) SvGROW(dst, need);
- if (dlen >= SvLEN(dst)) {
- Perl_croak(aTHX_
- "Destination couldn't be grown (the need may be
miscalculated).");
+ if (ddone >= SvLEN(dst)) {
+ Perl_croak(aTHX_ "Destination couldn't be grown.");
}
- dlen = SvLEN(dst);
- slen = tlen;
- break;
+ dlen = SvLEN(dst)-ddone-1;
+ d += ddone;
+ s += slen;
+ slen = tlen-sdone;
+ continue;
}
case ENCODE_NOREP:
@@ -553,13 +556,14 @@
return &PL_sv_undef;
}
}
- SvCUR_set(dst, dlen);
+ SvCUR_set(dst, dlen+ddone);
SvPOK_on(dst);
if (check) {
- if (slen < SvCUR(src)) {
- Move(s + slen, s, SvCUR(src) - slen, U8);
+ sdone = SvCUR(src) - (slen+sdone);
+ if (sdone) {
+ Move(s + slen, SvPVX(src), sdone , U8);
}
- SvCUR_set(src, SvCUR(src) - slen);
+ SvCUR_set(src, sdone);
*SvEND(src) = '\0';
}
}
End of Patch.