Skip to content

Commit ed4d129

Browse files
committed
Make :bytes actually pop off non-byte layers
1 parent ffc2a04 commit ed4d129

File tree

2 files changed

+29
-15
lines changed

2 files changed

+29
-15
lines changed

lib/PerlIO.pm

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -175,17 +175,10 @@ between valid UTF-8 bytes and valid Unicode characters.
175175
176176
=item :bytes
177177
178-
This is the inverse of the C<:utf8> pseudo-layer. It turns off the flag
179-
on the layer below so that data read from it is considered to
180-
be Perl's internal downgraded encoding, thus interpreted as the native
181-
single-byte encoding of Latin-1 or EBCDIC. Likewise on output Perl will
182-
warn if a "wide" character (a codepoint not in the range 0..255) is
183-
written to a such a stream.
184-
185-
This is very dangerous to push on a handle using an C<:encoding> layer,
186-
as such a layer assumes to be working with Perl's internal upgraded
187-
encoding, so you will likely get a mangled result. Instead use C<:raw> or
188-
C<:pop> to remove encoding layers.
178+
This removes all layers that do unicode IO, such as C<:utf8> and
179+
C<:encoding>. It ensures that data read from it is considered to be
180+
"octets" i.e. characters in the range 0..255 only. Likewise on output perl
181+
will warn if a "wide" character is written to a such a stream.
189182
190183
=item :raw
191184
@@ -203,9 +196,9 @@ to add C<:perlio> to the PERLIO environment variable, or open the handle
203196
explicitly with that layer, to replace the platform default of C<:crlf>.
204197
205198
The implementation of C<:raw> is as a pseudo-layer which when "pushed"
206-
pops itself and then any layers which would modify the binary data stream.
207-
(Undoing C<:utf8> and C<:crlf> may be implemented by clearing flags
208-
rather than popping layers but that is an implementation detail.)
199+
pops itself and then any layers which do not declare themselves as suitable
200+
for binary data. (Undoing :crlf is implemented by clearing a flag rather
201+
than popping the layer but that is an implementation detail.)
209202
210203
As a consequence of the fact that C<:raw> normally pops layers,
211204
it usually only makes sense to have it as the only or first element in

perlio.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2270,12 +2270,33 @@ PERLIO_FUNCS_DECL(PerlIO_utf8) = {
22702270
NULL, /* set_ptrcnt */
22712271
};
22722272

2273+
IV
2274+
PerlIOBytes_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
2275+
{
2276+
PERL_UNUSED_CONTEXT;
2277+
PERL_UNUSED_ARG(mode);
2278+
PERL_UNUSED_ARG(arg);
2279+
PERL_UNUSED_ARG(tab);
2280+
if (PerlIOValid(f)) {
2281+
PerlIO* current = f;
2282+
while(!(PerlIOBase(current)->tab->kind & PERLIO_K_RAW)) {
2283+
/*PerlIO* next = PerlIONext(current);*/
2284+
PerlIO_flush(current);
2285+
PerlIO_pop(aTHX_ current);
2286+
/*current = next; */
2287+
}
2288+
PerlIOBase(f)->flags &= ~PERLIO_F_UTF8;
2289+
return 0;
2290+
}
2291+
return -1;
2292+
}
2293+
22732294
PERLIO_FUNCS_DECL(PerlIO_byte) = {
22742295
sizeof(PerlIO_funcs),
22752296
"bytes",
22762297
0,
22772298
PERLIO_K_MULTIARG,
2278-
PerlIOUtf8_pushed,
2299+
PerlIOBytes_pushed,
22792300
NULL,
22802301
PerlIOBase_open,
22812302
NULL,

0 commit comments

Comments
 (0)