> When I wrote Apache::Filter, I decided to implement an honest-to-god
> full-on emulation of Perl's filehandle reading routines, and in particular
> it should handle $/ properly. If you want to have a look at that code,
> perhaps a portion of it could be integrated into Apache.pm so it would
> behave correctly.
I looked at Apache.pm and Apache::Filter.pm. There is a significant
difference: Apache::Filter "reads" from a string, while Apache.pm must
receive it's information from a function akin to sysread().
Alternative 1: Read the whole content into a string and fetch lines from
that string as in Apache::Filter. I think this is a bad idea, since it
might
defy the purpose of only reading a line at a time.
Alternative 2: Something like these (completely untested) modifications
to Apache.pm:
$Apache::READ_BLOCK_SIZE = 8*1024; # Some random number.
# Notes:
# - $r->read() should return undef() (or at least false) on failure.
# - $r->read() should accept an optional 'offset' arg like
sysread().
# - Is it appropriate and possible to add fields to $r? Look into
# notes() and pnotes() as an alternative to $r->{'content_buf'}
# and $r->{'content_remain'} if not.
# - $/ eq '' not handled by this READLINE().
sub READLINE {
my ($r) = @_;
# $r->{'content_buf' } Data fetched from client, but not yet
returned.
# $r->{'content_remain'} Number of bytes remaining to be read.
my $line; # Line found.
my @line; # Lines found.
my $pos; # Index of $/ substring inside of buffer.
my $num_bytes; # Number of bytes to read.
my $block; # Block just read.
# First pass?
if (!defined($self->{'content_buf'})) {
# Init data. This could be done in new().
$r->{'content_buf' } = '';
$r->{'content_remain'} = $r->header_in('Content-length');
}
# Exit with error if past end of file.
if (!$self->{'content_remain'} && !length($self->{'content_buf'}))
{
return wantarray() ? () : undef();
}
# List context?
if (wantarray()) {
# Read remainder of of input (with error checking).
$r->read($block='', $self->{'content_remain'});
return () unless (defined($block));
$self->{'content_buf'} .= $block;
# Divide into lines.
@line = $self->{'content_buf'} =~ m#(.*?\Q$/\E|.+(?!\Q$/\E))#gs;
# Return the lines.
$self->{'content_buf' } = '';
$self->{'content_remain'} = 0;
return @line;
}
for (;;) {
# EOL found?
if (defined($/) && ($pos = index($self->{'content_buf'}, $/)) >=
0) {
# Return the line.
$line = substr($self->{'content_buf'}, 0,
$pos);
$self->{'content_buf'} = substr($self->{'content_buf'}, $pos);
return $line;
}
# EOF reached?
if (!$self->{'content_remain'}) {
# Return last chunk.
$line = $self->{'content_buf'};
$self->{'content_buf' } = '';
$self->{'content_remain'} = 0;
return $line;
}
# Read another block of input (with error checking).
$num_bytes = ($self->{'content_remain'} <
$Apache::READ_BLOCK_SIZE
? $self->{'content_remain'}
: $Apache::READ_BLOCK_SIZE;
);
$r->read($block='', $num_bytes);
return undef() unless (defined($block));
$self->{'content_buf' } .= $block;
$self->{'content_remain'} -= $num_bytes;
}
}
ELB
--
Eric L. Brine | Chicken: The egg's way of making more eggs.
[EMAIL PROTECTED] | Do you always hit the nail on the thumb?
ICQ# 4629314 | An optimist thinks thorn bushes have roses.