return $html
}
+sub getlines {
+ my $self = shift;
+ die "Needs to be array context"
+ unless wantarray;
+ my @lines;
+ while (my $chunk = $self->getline) {
+ push @lines, $chunk;
+ }
+ return @lines;
+}
+
+## See: http://perldoc.perl.org/functions/read.html for read spec
+
+sub read {
+ my ($self, $buff, $len, $off) = @_;
+ $off = defined $off ? $off : 0;
+ $self->{_pos} = defined $self->{_pos} ? $self->{_pos} + $off : $off;
+ my $html = $self->{_html} ||= join '', $self->getlines;
+ return if $self->{_pos} > length $html;
+ $_[1] = substr $html, $self->{_pos}, $len;
+ unless(my $overflow = $len - length($buff)) {
+ $_[1] .= "\0" x $overflow;
+ }
+ $self->{_pos} += $len;
+}
+
sub close { "The door shuts behind you with a ominous boom" }
1;
+
+=head1 NAME
+
+HTML::Zoom::ReadFH - IO::FileHandler like methods on Zoom
+
+=head1 SYNOPSIS
+
+ my $zoom = HTML::Zoom->from_file($html_template);
+
+ #... zoom select modifications
+
+ my $fh = $zoom->to_fh;
+
+=head1 DESCRIPTION
+
+If you have a L<HTML::Zoom> object and need to render it as something very much
+like a FileHandle, this is the way to do it. Currently the code is written in
+a minimal manner. There's just enough support to enable this for L<Plack> and
+L<Catalyst>.
+
+=head1 METHODS
+
+This class supports the following methods.
+
+=head2 getline
+
+ my $fh = $zoom->to_fh;
+ my $line = $fh->getline;
+
+An L<IO::Handle> like C<getline> method.
+
+=head2 getlines
+
+ my $fh = $zoom->to_fh;
+ my @lines = $fh->getlines;
+
+An L<IO::Handle> like C<getlines> method.
+
+=head2 read
+
+ my $fh = $zoom->to_fh;
+ my $buff;
+ $zoom->read($buff, $length, $offset);
+
+An L<IO::Handle> like C<read> method.
+
+=head2 close
+
+Currently is a NOP
+
+=head1 NOTES
+
+ jnap: so to make the "to_fh" work for catalyst looks like I need to add a read
+ method (like "$io->read ( BUF, LEN, [OFFSET] )") to HTML::Zoom::ReadFH
+ jnap: any thoughts or objections?
+ mst: jnap: fine by me
+ mst: it's only as minimal as it is because I implemented enough to make the
+ Plack handler I was using happy and moved on
+ jnap: cool, thanks, figured so
+ mst: please also add a comment in ReadFH to that effect
+ mst: so the next person to find they need something can turn straight up with a patch
+
+Please remember that a patch acceptable to mst would include a test case.
+
+=head1 ALSO SEE
+
+L<HTML::Zoom>
+
+=head1 AUTHORS
+
+See L<HTML::Zoom> for authors.
+
+=head1 LICENSE
+
+See L<HTML::Zoom> for the license.
+
+=cut
+
--- /dev/null
+use strict;
+use warnings FATAL => 'all';
+
+use HTML::Zoom;
+use Test::More tests => 12;
+
+ok my $zoom = HTML::Zoom->from_html(<<HTML);
+<html>
+ <head>
+ <title>Hi!</title>
+ </head>
+ <body id="content-area">
+ <h1>Test</h1>
+ <div>
+ <p class="first-para">Some stuff</p>
+ <p class="boday-para">More stuff</p>
+ </div>
+ <p id="footer">Copryright 2222</p>
+ </body>
+</html>
+HTML
+
+ok my $fh = $zoom->to_fh,
+ 'got filehandle';
+
+ok my $html = $zoom->to_html,
+ 'got html';
+
+ok my $lines = join('', $zoom->to_fh->getlines),
+ 'got joined lines';
+
+is $html, $lines,
+ 'straight html is same as lines';
+
+{
+ $fh->read(my $buff, 2);
+
+ ok $buff,
+ 'got a populated buffer';
+
+ is $buff, '<h',
+ 'got expected info in buffer';
+}
+
+{
+ $fh->read(my $buff, 4);
+
+ ok $buff,
+ 'got a populated buffer';
+
+ is $buff, 'tml>',
+ 'got expected info in buffer';
+}
+
+{
+ $fh->read(my $buff, 4, 14);
+
+ ok $buff,
+ 'got a populated buffer';
+
+ is $buff, '<tit',
+ 'got expected info in buffer';
+}
+
+{
+ my @lines;
+ while($fh->read(my $buff, 15)) {
+ push @lines, $buff;
+ }
+
+ is $#lines, 15,
+ 'correct number of lines';
+}