1 #define PERL_NO_GET_CONTEXT 2 #include "EXTERN.h" 3 #include "perl.h" 4 #include "XSUB.h" 5 #define U8 U8 6 7 #define OUR_DEFAULT_FB "Encode::PERLQQ" 8 9 #if defined(USE_PERLIO) && !defined(USE_SFIO) 10 11 /* Define an encoding "layer" in the perliol.h sense. 12 13 The layer defined here "inherits" in an object-oriented sense from 14 the "perlio" layer with its PerlIOBuf_* "methods". The 15 implementation is particularly efficient as until Encode settles 16 down there is no point in tryint to tune it. 17 18 The layer works by overloading the "fill" and "flush" methods. 19 20 "fill" calls "SUPER::fill" in perl terms, then calls the encode OO 21 perl API to convert the encoded data to UTF-8 form, then copies it 22 back to the buffer. The "base class's" read methods then see the 23 UTF-8 data. 24 25 "flush" transforms the UTF-8 data deposited by the "base class's 26 write method in the buffer back into the encoded form using the 27 encode OO perl API, then copies data back into the buffer and calls 28 "SUPER::flush. 29 30 Note that "flush" is _also_ called for read mode - we still do the 31 (back)-translate so that the base class's "flush" sees the 32 correct number of encoded chars for positioning the seek 33 pointer. (This double translation is the worst performance issue - 34 particularly with all-perl encode engine.) 35 36 */ 37 38 #include "perliol.h" 39 40 typedef struct { 41 PerlIOBuf base; /* PerlIOBuf stuff */ 42 SV *bufsv; /* buffer seen by layers above */ 43 SV *dataSV; /* data we have read from layer below */ 44 SV *enc; /* the encoding object */ 45 SV *chk; /* CHECK in Encode methods */ 46 int flags; /* Flags currently just needs lines */ 47 int inEncodeCall; /* trap recursive encode calls */ 48 } PerlIOEncode; 49 50 #define NEEDS_LINES 1 51 52 SV * 53 PerlIOEncode_getarg(pTHX_ PerlIO * f, CLONE_PARAMS * param, int flags) 54 { 55 PerlIOEncode *e = PerlIOSelf(f, PerlIOEncode); 56 SV *sv = &PL_sv_undef; 57 PERL_UNUSED_ARG(param); 58 PERL_UNUSED_ARG(flags); 59 if (e->enc) { 60 dSP; 61 /* Not 100% sure stack swap is right thing to do during dup ... */ 62 PUSHSTACKi(PERLSI_MAGIC); 63 SPAGAIN; 64 ENTER; 65 SAVETMPS; 66 PUSHMARK(sp); 67 XPUSHs(e->enc); 68 PUTBACK; 69 if (call_method("name", G_SCALAR) == 1) { 70 SPAGAIN; 71 sv = newSVsv(POPs); 72 PUTBACK; 73 } 74 FREETMPS; 75 LEAVE; 76 POPSTACK; 77 } 78 return sv; 79 } 80 81 IV 82 PerlIOEncode_pushed(pTHX_ PerlIO * f, const char *mode, SV * arg, PerlIO_funcs *tab) 83 { 84 PerlIOEncode *e = PerlIOSelf(f, PerlIOEncode); 85 dSP; 86 IV code = PerlIOBuf_pushed(aTHX_ f, mode, Nullsv,tab); 87 SV *result = Nullsv; 88 89 PUSHSTACKi(PERLSI_MAGIC); 90 SPAGAIN; 91 92 ENTER; 93 SAVETMPS; 94 95 PUSHMARK(sp); 96 XPUSHs(arg); 97 PUTBACK; 98 if (call_pv("Encode::find_encoding", G_SCALAR) != 1) { 99 /* should never happen */ 100 Perl_die(aTHX_ "Encode::find_encoding did not return a value"); 101 return -1; 102 } 103 SPAGAIN; 104 result = POPs; 105 PUTBACK; 106 107 if (!SvROK(result) || !SvOBJECT(SvRV(result))) { 108 e->enc = Nullsv; 109 if (ckWARN_d(WARN_IO)) 110 Perl_warner(aTHX_ packWARN(WARN_IO), "Cannot find encoding \"%" SVf "\"", 111 arg); 112 errno = EINVAL; 113 code = -1; 114 } 115 else { 116 117 /* $enc->renew */ 118 PUSHMARK(sp); 119 XPUSHs(result); 120 PUTBACK; 121 if (call_method("renew",G_SCALAR|G_EVAL) != 1 || SvTRUE(ERRSV)) { 122 if (ckWARN_d(WARN_IO)) 123 Perl_warner(aTHX_ packWARN(WARN_IO), "\"%" SVf "\" does not support renew method", 124 arg); 125 } 126 else { 127 SPAGAIN; 128 result = POPs; 129 PUTBACK; 130 } 131 e->enc = newSVsv(result); 132 PUSHMARK(sp); 133 XPUSHs(e->enc); 134 PUTBACK; 135 if (call_method("needs_lines",G_SCALAR|G_EVAL) != 1 || SvTRUE(ERRSV)) { 136 if (ckWARN_d(WARN_IO)) 137 Perl_warner(aTHX_ packWARN(WARN_IO), "\"%" SVf "\" does not support needs_lines", 138 arg); 139 } 140 else { 141 SPAGAIN; 142 result = POPs; 143 PUTBACK; 144 if (SvTRUE(result)) { 145 e->flags |= NEEDS_LINES; 146 } 147 } 148 PerlIOBase(f)->flags |= PERLIO_F_UTF8; 149 } 150 151 e->chk = newSVsv(get_sv("PerlIO::encoding::fallback", 0)); 152 e->inEncodeCall = 0; 153 154 FREETMPS; 155 LEAVE; 156 POPSTACK; 157 return code; 158 } 159 160 IV 161 PerlIOEncode_popped(pTHX_ PerlIO * f) 162 { 163 PerlIOEncode *e = PerlIOSelf(f, PerlIOEncode); 164 if (e->enc) { 165 SvREFCNT_dec(e->enc); 166 e->enc = Nullsv; 167 } 168 if (e->bufsv) { 169 SvREFCNT_dec(e->bufsv); 170 e->bufsv = Nullsv; 171 } 172 if (e->dataSV) { 173 SvREFCNT_dec(e->dataSV); 174 e->dataSV = Nullsv; 175 } 176 if (e->chk) { 177 SvREFCNT_dec(e->chk); 178 e->chk = Nullsv; 179 } 180 return 0; 181 } 182 183 STDCHAR * 184 PerlIOEncode_get_base(pTHX_ PerlIO * f) 185 { 186 PerlIOEncode *e = PerlIOSelf(f, PerlIOEncode); 187 if (!e->base.bufsiz) 188 e->base.bufsiz = 1024; 189 if (!e->bufsv) { 190 e->bufsv = newSV(e->base.bufsiz); 191 sv_setpvn(e->bufsv, "", 0); 192 } 193 e->base.buf = (STDCHAR *) SvPVX(e->bufsv); 194 if (!e->base.ptr) 195 e->base.ptr = e->base.buf; 196 if (!e->base.end) 197 e->base.end = e->base.buf; 198 if (e->base.ptr < e->base.buf 199 || e->base.ptr > e->base.buf + SvLEN(e->bufsv)) { 200 Perl_warn(aTHX_ " ptr %p(%p)%p", e->base.buf, e->base.ptr, 201 e->base.buf + SvLEN(e->bufsv)); 202 abort(); 203 } 204 if (SvLEN(e->bufsv) < e->base.bufsiz) { 205 SSize_t poff = e->base.ptr - e->base.buf; 206 SSize_t eoff = e->base.end - e->base.buf; 207 e->base.buf = (STDCHAR *) SvGROW(e->bufsv, e->base.bufsiz); 208 e->base.ptr = e->base.buf + poff; 209 e->base.end = e->base.buf + eoff; 210 } 211 if (e->base.ptr < e->base.buf 212 || e->base.ptr > e->base.buf + SvLEN(e->bufsv)) { 213 Perl_warn(aTHX_ " ptr %p(%p)%p", e->base.buf, e->base.ptr, 214 e->base.buf + SvLEN(e->bufsv)); 215 abort(); 216 } 217 return e->base.buf; 218 } 219 220 IV 221 PerlIOEncode_fill(pTHX_ PerlIO * f) 222 { 223 PerlIOEncode *e = PerlIOSelf(f, PerlIOEncode); 224 dSP; 225 IV code = 0; 226 PerlIO *n; 227 SSize_t avail; 228 229 if (PerlIO_flush(f) != 0) 230 return -1; 231 n = PerlIONext(f); 232 if (!PerlIO_fast_gets(n)) { 233 /* Things get too messy if we don't have a buffer layer 234 push a :perlio to do the job */ 235 char mode[8]; 236 n = PerlIO_push(aTHX_ n, &PerlIO_perlio, PerlIO_modestr(f,mode), Nullsv); 237 if (!n) { 238 Perl_die(aTHX_ "panic: cannot push :perlio for %p",f); 239 } 240 } 241 PUSHSTACKi(PERLSI_MAGIC); 242 SPAGAIN; 243 ENTER; 244 SAVETMPS; 245 retry: 246 avail = PerlIO_get_cnt(n); 247 if (avail <= 0) { 248 avail = PerlIO_fill(n); 249 if (avail == 0) { 250 avail = PerlIO_get_cnt(n); 251 } 252 else { 253 if (!PerlIO_error(n) && PerlIO_eof(n)) 254 avail = 0; 255 } 256 } 257 if (avail > 0 || (e->flags & NEEDS_LINES)) { 258 STDCHAR *ptr = PerlIO_get_ptr(n); 259 SSize_t use = (avail >= 0) ? avail : 0; 260 SV *uni; 261 char *s = NULL; 262 STRLEN len = 0; 263 e->base.ptr = e->base.end = (STDCHAR *) NULL; 264 (void) PerlIOEncode_get_base(aTHX_ f); 265 if (!e->dataSV) 266 e->dataSV = newSV(0); 267 if (SvTYPE(e->dataSV) < SVt_PV) { 268 sv_upgrade(e->dataSV,SVt_PV); 269 } 270 if (e->flags & NEEDS_LINES) { 271 /* Encoding needs whole lines (e.g. iso-2022-*) 272 search back from end of available data for 273 and line marker 274 */ 275 STDCHAR *nl = ptr+use-1; 276 while (nl >= ptr) { 277 if (*nl == '\n') { 278 break; 279 } 280 nl--; 281 } 282 if (nl >= ptr && *nl == '\n') { 283 /* found a line - take up to and including that */ 284 use = (nl+1)-ptr; 285 } 286 else if (avail > 0) { 287 /* No line, but not EOF - append avail to the pending data */ 288 sv_catpvn(e->dataSV, (char*)ptr, use); 289 PerlIO_set_ptrcnt(n, ptr+use, 0); 290 goto retry; 291 } 292 else if (!SvCUR(e->dataSV)) { 293 goto end_of_file; 294 } 295 } 296 if (SvCUR(e->dataSV)) { 297 /* something left over from last time - create a normal 298 SV with new data appended 299 */ 300 if (use + SvCUR(e->dataSV) > e->base.bufsiz) { 301 if (e->flags & NEEDS_LINES) { 302 /* Have to grow buffer */ 303 e->base.bufsiz = use + SvCUR(e->dataSV); 304 PerlIOEncode_get_base(aTHX_ f); 305 } 306 else { 307 use = e->base.bufsiz - SvCUR(e->dataSV); 308 } 309 } 310 sv_catpvn(e->dataSV,(char*)ptr,use); 311 } 312 else { 313 /* Create a "dummy" SV to represent the available data from layer below */ 314 if (SvLEN(e->dataSV) && SvPVX_const(e->dataSV)) { 315 Safefree(SvPVX_mutable(e->dataSV)); 316 } 317 if (use > (SSize_t)e->base.bufsiz) { 318 if (e->flags & NEEDS_LINES) { 319 /* Have to grow buffer */ 320 e->base.bufsiz = use; 321 PerlIOEncode_get_base(aTHX_ f); 322 } 323 else { 324 use = e->base.bufsiz; 325 } 326 } 327 SvPV_set(e->dataSV, (char *) ptr); 328 SvLEN_set(e->dataSV, 0); /* Hands off sv.c - it isn't yours */ 329 SvCUR_set(e->dataSV,use); 330 SvPOK_only(e->dataSV); 331 } 332 SvUTF8_off(e->dataSV); 333 PUSHMARK(sp); 334 XPUSHs(e->enc); 335 XPUSHs(e->dataSV); 336 XPUSHs(e->chk); 337 PUTBACK; 338 if (call_method("decode", G_SCALAR) != 1) { 339 Perl_die(aTHX_ "panic: decode did not return a value"); 340 } 341 SPAGAIN; 342 uni = POPs; 343 PUTBACK; 344 /* Now get translated string (forced to UTF-8) and use as buffer */ 345 if (SvPOK(uni)) { 346 s = SvPVutf8(uni, len); 347 #ifdef PARANOID_ENCODE_CHECKS 348 if (len && !is_utf8_string((U8*)s,len)) { 349 Perl_warn(aTHX_ "panic: decode did not return UTF-8 '%.*s'",(int) len,s); 350 } 351 #endif 352 } 353 if (len > 0) { 354 /* Got _something */ 355 /* if decode gave us back dataSV then data may vanish when 356 we do ptrcnt adjust - so take our copy now. 357 (The copy is a pain - need a put-it-here option for decode.) 358 */ 359 sv_setpvn(e->bufsv,s,len); 360 e->base.ptr = e->base.buf = (STDCHAR*)SvPVX(e->bufsv); 361 e->base.end = e->base.ptr + SvCUR(e->bufsv); 362 PerlIOBase(f)->flags |= PERLIO_F_RDBUF; 363 SvUTF8_on(e->bufsv); 364 365 /* Adjust ptr/cnt not taking anything which 366 did not translate - not clear this is a win */ 367 /* compute amount we took */ 368 use -= SvCUR(e->dataSV); 369 PerlIO_set_ptrcnt(n, ptr+use, (avail-use)); 370 /* and as we did not take it it isn't pending */ 371 SvCUR_set(e->dataSV,0); 372 } else { 373 /* Got nothing - assume partial character so we need some more */ 374 /* Make sure e->dataSV is a normal SV before re-filling as 375 buffer alias will change under us 376 */ 377 s = SvPV(e->dataSV,len); 378 sv_setpvn(e->dataSV,s,len); 379 PerlIO_set_ptrcnt(n, ptr+use, (avail-use)); 380 goto retry; 381 } 382 } 383 else { 384 end_of_file: 385 code = -1; 386 if (avail == 0) 387 PerlIOBase(f)->flags |= PERLIO_F_EOF; 388 else 389 PerlIOBase(f)->flags |= PERLIO_F_ERROR; 390 } 391 FREETMPS; 392 LEAVE; 393 POPSTACK; 394 return code; 395 } 396 397 IV 398 PerlIOEncode_flush(pTHX_ PerlIO * f) 399 { 400 PerlIOEncode *e = PerlIOSelf(f, PerlIOEncode); 401 IV code = 0; 402 403 if (e->bufsv) { 404 dSP; 405 SV *str; 406 char *s; 407 STRLEN len; 408 SSize_t count = 0; 409 if ((PerlIOBase(f)->flags & PERLIO_F_WRBUF) && (e->base.ptr > e->base.buf)) { 410 if (e->inEncodeCall) return 0; 411 /* Write case - encode the buffer and write() to layer below */ 412 PUSHSTACKi(PERLSI_MAGIC); 413 SPAGAIN; 414 ENTER; 415 SAVETMPS; 416 PUSHMARK(sp); 417 XPUSHs(e->enc); 418 SvCUR_set(e->bufsv, e->base.ptr - e->base.buf); 419 SvUTF8_on(e->bufsv); 420 XPUSHs(e->bufsv); 421 XPUSHs(e->chk); 422 PUTBACK; 423 e->inEncodeCall = 1; 424 if (call_method("encode", G_SCALAR) != 1) { 425 e->inEncodeCall = 0; 426 Perl_die(aTHX_ "panic: encode did not return a value"); 427 } 428 e->inEncodeCall = 0; 429 SPAGAIN; 430 str = POPs; 431 PUTBACK; 432 s = SvPV(str, len); 433 count = PerlIO_write(PerlIONext(f),s,len); 434 if ((STRLEN)count != len) { 435 code = -1; 436 } 437 FREETMPS; 438 LEAVE; 439 POPSTACK; 440 if (PerlIO_flush(PerlIONext(f)) != 0) { 441 code = -1; 442 } 443 if (SvCUR(e->bufsv)) { 444 /* Did not all translate */ 445 e->base.ptr = e->base.buf+SvCUR(e->bufsv); 446 return code; 447 } 448 } 449 else if ((PerlIOBase(f)->flags & PERLIO_F_RDBUF)) { 450 /* read case */ 451 /* if we have any untranslated stuff then unread that first */ 452 /* FIXME - unread is fragile is there a better way ? */ 453 if (e->dataSV && SvCUR(e->dataSV)) { 454 s = SvPV(e->dataSV, len); 455 count = PerlIO_unread(PerlIONext(f),s,len); 456 if ((STRLEN)count != len) { 457 code = -1; 458 } 459 SvCUR_set(e->dataSV,0); 460 } 461 /* See if there is anything left in the buffer */ 462 if (e->base.ptr < e->base.end) { 463 if (e->inEncodeCall) return 0; 464 /* Bother - have unread data. 465 re-encode and unread() to layer below 466 */ 467 PUSHSTACKi(PERLSI_MAGIC); 468 SPAGAIN; 469 ENTER; 470 SAVETMPS; 471 str = sv_newmortal(); 472 sv_upgrade(str, SVt_PV); 473 SvPV_set(str, (char*)e->base.ptr); 474 SvLEN_set(str, 0); 475 SvCUR_set(str, e->base.end - e->base.ptr); 476 SvPOK_only(str); 477 SvUTF8_on(str); 478 PUSHMARK(sp); 479 XPUSHs(e->enc); 480 XPUSHs(str); 481 XPUSHs(e->chk); 482 PUTBACK; 483 e->inEncodeCall = 1; 484 if (call_method("encode", G_SCALAR) != 1) { 485 e->inEncodeCall = 0; 486 Perl_die(aTHX_ "panic: encode did not return a value"); 487 } 488 e->inEncodeCall = 0; 489 SPAGAIN; 490 str = POPs; 491 PUTBACK; 492 s = SvPV(str, len); 493 count = PerlIO_unread(PerlIONext(f),s,len); 494 if ((STRLEN)count != len) { 495 code = -1; 496 } 497 FREETMPS; 498 LEAVE; 499 POPSTACK; 500 } 501 } 502 e->base.ptr = e->base.end = e->base.buf; 503 PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF | PERLIO_F_WRBUF); 504 } 505 return code; 506 } 507 508 IV 509 PerlIOEncode_close(pTHX_ PerlIO * f) 510 { 511 PerlIOEncode *e = PerlIOSelf(f, PerlIOEncode); 512 IV code; 513 if (PerlIOBase(f)->flags & PERLIO_F_RDBUF) { 514 /* Discard partial character */ 515 if (e->dataSV) { 516 SvCUR_set(e->dataSV,0); 517 } 518 /* Don't back decode and unread any pending data */ 519 e->base.ptr = e->base.end = e->base.buf; 520 } 521 code = PerlIOBase_close(aTHX_ f); 522 if (e->bufsv) { 523 /* This should only fire for write case */ 524 if (e->base.buf && e->base.ptr > e->base.buf) { 525 Perl_croak(aTHX_ "Close with partial character"); 526 } 527 SvREFCNT_dec(e->bufsv); 528 e->bufsv = Nullsv; 529 } 530 e->base.buf = NULL; 531 e->base.ptr = NULL; 532 e->base.end = NULL; 533 PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF | PERLIO_F_WRBUF); 534 return code; 535 } 536 537 Off_t 538 PerlIOEncode_tell(pTHX_ PerlIO * f) 539 { 540 PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf); 541 /* Unfortunately the only way to get a position is to (re-)translate, 542 the UTF8 we have in buffer and then ask layer below 543 */ 544 PerlIO_flush(f); 545 if (b->buf && b->ptr > b->buf) { 546 Perl_croak(aTHX_ "Cannot tell at partial character"); 547 } 548 return PerlIO_tell(PerlIONext(f)); 549 } 550 551 PerlIO * 552 PerlIOEncode_dup(pTHX_ PerlIO * f, PerlIO * o, 553 CLONE_PARAMS * params, int flags) 554 { 555 if ((f = PerlIOBase_dup(aTHX_ f, o, params, flags))) { 556 PerlIOEncode *fe = PerlIOSelf(f, PerlIOEncode); 557 PerlIOEncode *oe = PerlIOSelf(o, PerlIOEncode); 558 if (oe->enc) { 559 fe->enc = PerlIO_sv_dup(aTHX_ oe->enc, params); 560 } 561 } 562 return f; 563 } 564 565 SSize_t 566 PerlIOEncode_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count) 567 { 568 PerlIOEncode *e = PerlIOSelf(f, PerlIOEncode); 569 if (e->flags & NEEDS_LINES) { 570 SSize_t done = 0; 571 const char *ptr = (const char *) vbuf; 572 const char *end = ptr+count; 573 while (ptr < end) { 574 const char *nl = ptr; 575 while (nl < end && *nl++ != '\n') /* empty body */; 576 done = PerlIOBuf_write(aTHX_ f, ptr, nl-ptr); 577 if (done != nl-ptr) { 578 if (done > 0) { 579 ptr += done; 580 } 581 break; 582 } 583 ptr += done; 584 if (ptr[-1] == '\n') { 585 if (PerlIOEncode_flush(aTHX_ f) != 0) { 586 break; 587 } 588 } 589 } 590 return (SSize_t) (ptr - (const char *) vbuf); 591 } 592 else { 593 return PerlIOBuf_write(aTHX_ f, vbuf, count); 594 } 595 } 596 597 PerlIO_funcs PerlIO_encode = { 598 sizeof(PerlIO_funcs), 599 "encoding", 600 sizeof(PerlIOEncode), 601 PERLIO_K_BUFFERED|PERLIO_K_DESTRUCT, 602 PerlIOEncode_pushed, 603 PerlIOEncode_popped, 604 PerlIOBuf_open, 605 NULL, /* binmode - always pop */ 606 PerlIOEncode_getarg, 607 PerlIOBase_fileno, 608 PerlIOEncode_dup, 609 PerlIOBuf_read, 610 PerlIOBuf_unread, 611 PerlIOEncode_write, 612 PerlIOBuf_seek, 613 PerlIOEncode_tell, 614 PerlIOEncode_close, 615 PerlIOEncode_flush, 616 PerlIOEncode_fill, 617 PerlIOBase_eof, 618 PerlIOBase_error, 619 PerlIOBase_clearerr, 620 PerlIOBase_setlinebuf, 621 PerlIOEncode_get_base, 622 PerlIOBuf_bufsiz, 623 PerlIOBuf_get_ptr, 624 PerlIOBuf_get_cnt, 625 PerlIOBuf_set_ptrcnt, 626 }; 627 #endif /* encode layer */ 628 629 MODULE = PerlIO::encoding PACKAGE = PerlIO::encoding 630 631 PROTOTYPES: ENABLE 632 633 BOOT: 634 { 635 SV *chk = get_sv("PerlIO::encoding::fallback", GV_ADD|GV_ADDMULTI); 636 /* 637 * we now "use Encode ()" here instead of 638 * PerlIO/encoding.pm. This avoids SEGV when ":encoding()" 639 * is invoked without prior "use Encode". -- dankogai 640 */ 641 PUSHSTACKi(PERLSI_MAGIC); 642 SPAGAIN; 643 if (!get_cvs(OUR_DEFAULT_FB, 0)) { 644 #if 0 645 /* This would just be an irritant now loading works */ 646 Perl_warner(aTHX_ packWARN(WARN_IO), ":encoding without 'use Encode'"); 647 #endif 648 ENTER; 649 /* Encode needs a lot of stack - it is likely to move ... */ 650 PUTBACK; 651 /* The SV is magically freed by load_module */ 652 load_module(PERL_LOADMOD_NOIMPORT, newSVpvn("Encode", 6), Nullsv, Nullsv); 653 SPAGAIN; 654 LEAVE; 655 } 656 PUSHMARK(sp); 657 PUTBACK; 658 if (call_pv(OUR_DEFAULT_FB, G_SCALAR) != 1) { 659 /* should never happen */ 660 Perl_die(aTHX_ "%s did not return a value",OUR_DEFAULT_FB); 661 } 662 SPAGAIN; 663 sv_setsv(chk, POPs); 664 PUTBACK; 665 #ifdef PERLIO_LAYERS 666 PerlIO_define_layer(aTHX_ &PerlIO_encode); 667 #endif 668 POPSTACK; 669 } 670