1POE::Filter(3)        User Contributed Perl Documentation       POE::Filter(3)
2
3
4

NAME

6       POE::Filter - protocol abstractions for POE::Wheel and standalone use
7

SYNOPSIS

9       To use with POE::Wheel classes, pass a POE::Filter object to one of the
10       "...Filter" constructor parameters:
11
12         #!perl
13
14         use POE qw(Filter::Line Wheel::FollowTail);
15
16         POE::Session->create(
17           inline_states => {
18             _start => sub {
19               $_[HEAP]{tailor} = POE::Wheel::FollowTail->new(
20                 Filename => "/var/log/system.log",
21                 InputEvent => "got_log_line",
22                 Filter => POE::Filter::Line->new(),
23               );
24             },
25             got_log_line => sub {
26               print "Log: $_[ARG0]\n";
27             }
28           }
29         );
30
31         POE::Kernel->run();
32         exit;
33
34       Standalone use without POE:
35
36         #!perl
37
38         use warnings;
39         use strict;
40         use POE::Filter::Line;
41
42         my $filter = POE::Filter::Line->new( Literal => "\n" );
43
44         # Prints three lines: one, two three.
45
46         $filter->get_one_start(["one\ntwo\nthr", "ee\nfour"]);
47         while (1) {
48           my $line = $filter->get_one();
49           last unless @$line;
50           print $line->[0], "\n";
51         }
52
53         # Prints two lines: four, five.
54
55         $filter->get_one_start(["\nfive\n"]);
56         while (1) {
57           my $line = $filter->get_one();
58           last unless @$line;
59           print $line->[0], "\n";
60         }
61

DESCRIPTION

63       POE::Filter objects plug into the wheels and define how the data will
64       be serialized for writing and parsed after reading.  POE::Wheel objects
65       are responsible for moving data, and POE::Filter objects define how the
66       data should look.
67
68       POE::Filter objects are simple by design.  They do not use POE
69       internally, so they are limited to serialization and parsing.  This may
70       complicate implementation of certain protocols (like HTTP 1.x), but it
71       allows filters to be used in stand-alone programs.
72
73       Stand-alone use is very important.  It allows application developers to
74       create lightweight blocking libraries that may be used as simple
75       clients for POE servers.  POE::Component::IKC::ClientLite is a notable
76       example.  This lightweight, blocking event-passing client supports thin
77       clients for gridded POE applications.  The canonical use case is to
78       inject events into an IKC application or grid from CGI interfaces,
79       which require lightweight resource use.
80
81       POE filters and drivers pass data in array references.  This is
82       slightly awkward, but it minimizes the amount of data that must be
83       copied on Perl's stack.
84

PUBLIC INTERFACE

86       All POE::Filter classes must support the minimal interface, defined
87       here.  Specific filters may implement and document additional methods.
88
89   new PARAMETERS
90       new() creates and initializes a new filter.  Constructor parameters
91       vary from one POE::Filter subclass to the next, so please consult the
92       documentation for your desired filter.
93
94   clone
95       clone() creates and initializes a new filter based on the constructor
96       parameters of the existing one.  The new filter is a near-identical
97       copy, except that its buffers are empty.
98
99       Certain components, such as POE::Component::Server::TCP, use clone().
100       These components accept a master or template filter at creation time,
101       then clone() that filter for each new connection.
102
103         my $new_filter = $old_filter->clone();
104
105   get_one_start ARRAYREF
106       get_one_start() accepts an array reference containing unprocessed
107       stream chunks.  The chunks are added to the filter's internal buffer
108       for parsing by get_one().
109
110       The "SYNOPSIS" shows get_one_start() in use.
111
112   get_one
113       get_one() parses zero or one complete item from the filter's internal
114       buffer.  The data is returned as an ARRAYREF suitable for passing to
115       another filter or a POE::Wheel object.  Filters will return empty
116       ARRAYREFs if they don't have enough raw data to build a complete item.
117
118       get_one() is the lazy form of get().  It only parses only one item at a
119       time from the filter's buffer.  This is vital for applications that may
120       switch filters in mid-stream, as it ensures that the right filter is in
121       use at any given time.
122
123       The "SYNOPSIS" shows get_one() in use.  Note how it assumes the return
124       is always an ARRAYREF, and it implicitly handles empty ones.
125
126   get ARRAYREF
127       get() is the greedy form of get_one().  It accepts an array reference
128       containing unprocessed stream chunks, and it adds that data to the
129       filter's internal buffer.  It then parses as many full items as
130       possible from the buffer and returns them in another array reference.
131       Any unprocessed data remains in the filter's buffer for the next call.
132
133       As with get_one(), get() will return an empty array reference if the
134       filter doesn't contain enough raw data to build a complete item.
135
136       In fact, get() is implemented in POE::Filter in terms of
137       get_one_start() and get_one().
138
139       Here's the get() form of the SYNOPSIS stand-alone example:
140
141         #!perl
142
143         use warnings;
144         use strict;
145         use POE::Filter::Line;
146
147         my $filter = POE::Filter::Line->new( Literal => "\n" );
148
149         # Prints three lines: one, two three.
150
151         my $lines = $filter->get(["one\ntwo\nthr", "ee\nfour"]);
152         foreach my $line (@$lines) {
153           print "$line\n";
154         }
155
156         # Prints two lines: four, five.
157
158         $lines = $filter->get(["\nfive\n"]);
159         foreach my $line (@$lines) {
160           print "$line\n";
161         }
162
163       get() should not be used with wheels that support filter switching.
164       Its greedy nature means that it often parses streams well in advance of
165       a wheel's events.  By the time an application changes the wheel's
166       filter, it's too late: The old filter has already parsed the rest of
167       the received data.
168
169       Consider a stream of letters, numbers, and periods.  The periods signal
170       when to switch filters from one that parses letters to one that parses
171       numbers.
172
173       In our hypothetical application, letters must be handled one at a time,
174       but numbers may be handled in chunks.  We'll use POE::Filter::Block
175       with a BlockSize of 1 to parse letters, and POE::FIlter::Line with a
176       Literal terminator of "." to handle numbers.
177
178       Here's the sample stream:
179
180         abcdefg.1234567.hijklmnop.890.q
181
182       We'll start with a ReadWrite wheel configured to parse characters.
183
184         $_[HEAP]{wheel} = POE::Wheel::ReadWrite->new(
185           Filter => POE::Filter::Block->new( BlockSize => 1 ),
186           Handle => $socket,
187           InputEvent => "got_letter",
188         );
189
190       The "got_letter" handler will be called 8 times.  One for each letter
191       from a through g, and once for the period following g.  Upon receiving
192       the period, it will switch the wheel into number mode.
193
194         sub handle_letter {
195           my $letter = $_[ARG0];
196           if ($letter eq ".") {
197             $_[HEAP]{wheel}->set_filter(
198               POE::Filter::Line->new( Literal => "." )
199             );
200             $_[HEAP]{wheel}->event( InputEvent => "got_number" );
201           }
202           else {
203             print "Got letter: $letter\n";
204           }
205         }
206
207       If the greedy get() were used, the entire input stream would have been
208       parsed as characters in advance of the first handle_letter() call.  The
209       set_filter() call would have been moot, since there would be no data
210       left to be parsed.
211
212       The "got_number" handler receives contiguous runs of digits as period-
213       terminated lines.  The greedy get() would cause a similar problem as
214       above.
215
216         sub handle_numbers {
217           my $numbers = $_[ARG0];
218           print "Got number(s): $numbers\n";
219           $_[HEAP]->{wheel}->set_filter(
220             POE::Filter::Block->new( BlockSize => 1 )
221           );
222           $_[HEAP]->{wheel}->event( InputEvent => "got_letter" );
223         }
224
225       So don't do it!
226
227   put ARRAYREF
228       put() serializes items into a stream of octets that may be written to a
229       file or sent across a socket.  It accepts a reference to a list of
230       items, and it returns a reference to a list of marshalled stream
231       chunks.  The number of output chunks is not necessarily related to the
232       number of input items.
233
234       In stand-alone use, put()'s output may be sent directly:
235
236         my $line_filter = POE::Filter::Line->new();
237         my $lines = $line_filter->put(\@list_of_things);
238         foreach my $line (@$lines) {
239           print $line;
240         }
241
242       The list reference it returns may be passed directly to a driver or
243       filter.  Drivers and filters deliberately share the same put()
244       interface so that things like this are possible:
245
246         $driver->put(
247           $transfer_encoding_filter->put(
248             $content_encoding_filter->put(
249               \@items
250             )
251           )
252         );
253
254         1 while $driver->flush(\*STDOUT);
255
256   get_pending
257       get_pending() returns any data remaining in a filter's input buffer.
258       The filter's input buffer is not cleared, however.  get_pending()
259       returns a list reference if there's any data, or undef if the filter
260       was empty.
261
262       POE::Wheel objects use get_pending() during filter switching.
263       Unprocessed data is fetched from the old filter with get_pending() and
264       injected into the new filter with get_one_start().
265
266         use POE::Filter::Line;
267         use POE::Filter::Stream;
268
269         my $line_filter = POE::Filter::Line->new();
270         $line_filter->get_one_start([ "not a complete line" ]);
271
272         my $stream_filter = POE::Filter::Stream->new();
273         my $line_buffer = $line_filter->get_pending();
274         $stream_filter->get_one_start($line_buffer) if $line_buffer;
275
276         print "Stream: $_\n" foreach (@{ $stream_filter->get_one });
277
278       Full items are serialized whole, so there is no corresponding "put"
279       buffer or accessor.
280

SEE ALSO

282       The SEE ALSO section in POE contains a table of contents covering the
283       entire POE distribution.
284
285       POE is bundled with the following filters:
286
287       POE::Filter::Block POE::Filter::Grep POE::Filter::HTTPD
288       POE::Filter::Line POE::Filter::Map POE::Filter::RecordBlock
289       POE::Filter::Reference POE::Filter::Stackable POE::Filter::Stream
290

BUGS

292       In theory, filters should be interchangeable.  In practice, stream and
293       block protocols tend to be incompatible.
294

AUTHORS & COPYRIGHTS

296       Please see POE for more information about authors and contributors.
297
298
299
300perl v5.38.0                      2023-07-21                    POE::Filter(3)
Impressum