Commit | Line | Data |
bf5a23d0 |
1 | package HTML::Zoom::ReadFH; |
2 | |
1cf03540 |
3 | use strictures 1; |
10a73720 |
4 | use Symbol; |
5 | |
6 | sub TIEHANDLE { return shift } |
7 | sub FILENO { return undef } |
8 | sub READ { return shift->read(@_) } |
9 | sub CLOSE { return shift->close(@_) } |
10 | sub OPEN { return shift->open(@_)} |
11 | |
12 | sub open { 1 } |
13 | sub opened { 1 } |
14 | sub close { "The door shuts behind you with a ominous boom" } |
bf5a23d0 |
15 | |
16 | sub from_zoom { |
17 | my ($class, $zoom) = @_; |
10a73720 |
18 | my $self = bless Symbol::gensym(), ref($class) || $class; |
19 | tie *$self, $self; |
20 | *$self->{_zoom} = $zoom; |
21 | $self->open; |
22 | return $self; |
bf5a23d0 |
23 | } |
24 | |
25 | sub to_zoom { |
26 | my $self = shift; |
27 | # A small defense against accidental footshots. I hope. |
28 | # If this turns out to merely re-aim the gun at your left nipple, please |
29 | # come complain with a documented use case and we'll discuss deleting it. |
30 | die "Already started reading - there ain't no going back now" |
10a73720 |
31 | if *$self->{_stream}; |
32 | *$self->{_zoom} |
bf5a23d0 |
33 | } |
34 | |
35 | sub getline { |
36 | my $self = shift; |
37 | my $html; |
10a73720 |
38 | my $stream = *$self->{_stream} ||= *$self->{_zoom}->to_stream; |
39 | my $producer = *$self->{_producer} ||= *$self->{_zoom}->zconfig->producer; |
bf5a23d0 |
40 | while (my ($evt) = $stream->next) { |
41 | $html .= $producer->event_to_html($evt); |
42 | last if $evt->{flush}; |
43 | } |
44 | return $html |
45 | } |
46 | |
d3bcbd89 |
47 | sub getlines { |
48 | my $self = shift; |
49 | die "Needs to be array context" |
50 | unless wantarray; |
51 | my @lines; |
52 | while (my $chunk = $self->getline) { |
53 | push @lines, $chunk; |
54 | } |
55 | return @lines; |
56 | } |
57 | |
d3bcbd89 |
58 | sub read { |
59 | my ($self, $buff, $len, $off) = @_; |
60 | $off = defined $off ? $off : 0; |
10a73720 |
61 | *$self->{_pos} = defined *$self->{_pos} ? *$self->{_pos} + $off : $off; |
62 | my $html = *$self->{_html} ||= join '', $self->getlines; |
63 | return if length($html) < *$self->{_pos}; |
64 | $_[1] = substr $html, *$self->{_pos}, $len; |
d3bcbd89 |
65 | unless(my $overflow = $len - length($buff)) { |
66 | $_[1] .= "\0" x $overflow; |
67 | } |
10a73720 |
68 | *$self->{_pos} += $len; |
d3bcbd89 |
69 | } |
70 | |
10a73720 |
71 | sub stat { |
72 | |
73 | warn "GOT THE CUSSTOM STAT"; |
74 | |
75 | my $self = shift; |
76 | return 1 unless wantarray; |
77 | my $html = *$self->{_html} ||= join '', $self->getlines; |
78 | my $len = length $html; |
79 | |
80 | return ( |
81 | undef, undef, # dev, ino |
82 | 0666, # filemode |
83 | 1, # links |
84 | $>, # user id |
85 | $), # group id |
86 | undef, # device id |
87 | $len, # size |
88 | undef, # atime |
89 | undef, # mtime |
90 | undef, # ctime |
91 | 512, # blksize |
92 | int(($len+511)/512) # blocks |
93 | ); |
94 | } |
bf5a23d0 |
95 | |
96 | 1; |
d3bcbd89 |
97 | |
98 | =head1 NAME |
99 | |
100 | HTML::Zoom::ReadFH - IO::FileHandler like methods on Zoom |
101 | |
102 | =head1 SYNOPSIS |
103 | |
104 | my $zoom = HTML::Zoom->from_file($html_template); |
105 | |
106 | #... zoom select modifications |
107 | |
108 | my $fh = $zoom->to_fh; |
109 | |
110 | =head1 DESCRIPTION |
111 | |
112 | If you have a L<HTML::Zoom> object and need to render it as something very much |
113 | like a FileHandle, this is the way to do it. Currently the code is written in |
114 | a minimal manner. There's just enough support to enable this for L<Plack> and |
115 | L<Catalyst>. |
116 | |
117 | =head1 METHODS |
118 | |
119 | This class supports the following methods. |
120 | |
121 | =head2 getline |
122 | |
123 | my $fh = $zoom->to_fh; |
124 | my $line = $fh->getline; |
125 | |
126 | An L<IO::Handle> like C<getline> method. |
127 | |
128 | =head2 getlines |
129 | |
130 | my $fh = $zoom->to_fh; |
131 | my @lines = $fh->getlines; |
132 | |
133 | An L<IO::Handle> like C<getlines> method. |
134 | |
135 | =head2 read |
136 | |
137 | my $fh = $zoom->to_fh; |
138 | my $buff; |
139 | $zoom->read($buff, $length, $offset); |
140 | |
141 | An L<IO::Handle> like C<read> method. |
142 | |
143 | =head2 close |
144 | |
145 | Currently is a NOP |
146 | |
147 | =head1 NOTES |
148 | |
149 | jnap: so to make the "to_fh" work for catalyst looks like I need to add a read |
150 | method (like "$io->read ( BUF, LEN, [OFFSET] )") to HTML::Zoom::ReadFH |
151 | jnap: any thoughts or objections? |
152 | mst: jnap: fine by me |
153 | mst: it's only as minimal as it is because I implemented enough to make the |
154 | Plack handler I was using happy and moved on |
155 | jnap: cool, thanks, figured so |
156 | mst: please also add a comment in ReadFH to that effect |
157 | mst: so the next person to find they need something can turn straight up with a patch |
158 | |
159 | Please remember that a patch acceptable to mst would include a test case. |
160 | |
161 | =head1 ALSO SEE |
162 | |
163 | L<HTML::Zoom> |
164 | |
165 | =head1 AUTHORS |
166 | |
167 | See L<HTML::Zoom> for authors. |
168 | |
169 | =head1 LICENSE |
170 | |
171 | See L<HTML::Zoom> for the license. |
172 | |
173 | =cut |
174 | |