home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / xampp / xampp-perl-addon-1.4.9-installer.exe / Stackable.pm < prev    next >
Encoding:
Perl POD Document  |  2003-11-21  |  5.3 KB  |  211 lines

  1. # 2001/01/25 shizukesa@pobox.com
  2.  
  3. # This implements a filter stack, which turns ReadWrite into something
  4. # very, very interesting.
  5.  
  6. # 2001-07-26 RCC: I have no idea how to make this support get_one, so
  7. # I'm not going to right now.
  8.  
  9. package POE::Filter::Stackable;
  10.  
  11. use strict;
  12.  
  13. use vars qw($VERSION);
  14. $VERSION = do {my@r=(q$Revision: 1.5 $=~/\d+/g);sprintf"%d."."%04d"x$#r,@r};
  15.  
  16. use Carp qw(croak);
  17.  
  18. sub FILTERS () { 0 }
  19.  
  20. #------------------------------------------------------------------------------
  21.  
  22. sub new {
  23.   my $type = shift;
  24.   croak "$type must be given an even number of parameters" if @_ & 1;
  25.   my %params = @_;
  26.  
  27.   my $self = bless [], $type;
  28.  
  29.   $self->[FILTERS] = $params{Filters};
  30.  
  31.   $self;
  32. }
  33.  
  34. #------------------------------------------------------------------------------
  35.  
  36. sub get {
  37.   my ($self, $data) = @_;
  38.   foreach my $filter (@{$self->[FILTERS]}) {
  39.     $data = $filter->get($data);
  40.     last unless @$data;
  41.   }
  42.   $data;
  43. }
  44.  
  45. #------------------------------------------------------------------------------
  46.  
  47. sub put {
  48.   my ($self, $data) = @_;
  49.   foreach my $filter (reverse @{$self->[FILTERS]}) {
  50.     $data = $filter->put($data);
  51.     last unless @$data;
  52.   }
  53.   $data;
  54. }
  55.  
  56. #------------------------------------------------------------------------------
  57.  
  58. sub get_pending {
  59.   my ($self) = @_;
  60.   my $data;
  61.   for (@{$self->[FILTERS]}) {
  62.     $_->put($data) if $data && @{$data};
  63.     $data = $_->get_pending;
  64.   }
  65.   $data || [];
  66. }
  67.  
  68. #------------------------------------------------------------------------------
  69.  
  70. sub filter_types {
  71.    map { ((ref $_) =~ /::(\w+)$/)[0] } @{$_[0]->[FILTERS]};
  72. }
  73.  
  74. #------------------------------------------------------------------------------
  75.  
  76. sub filters {
  77.   @{$_[0]->[FILTERS]};
  78. }
  79.  
  80. #------------------------------------------------------------------------------
  81.  
  82. sub shift {
  83.   my ($self) = @_;
  84.   my $filter = shift @{$self->[FILTERS]};
  85.   $self->[FILTERS]->[0]->put($filter->get_pending || []);
  86.   $filter;
  87. }
  88.  
  89. #------------------------------------------------------------------------------
  90.  
  91. sub unshift {
  92.   my ($self, @filters) = @_;
  93.   unshift(@{$self->[FILTERS]}, @filters);
  94. }
  95.  
  96. #------------------------------------------------------------------------------
  97.  
  98. sub push {
  99.   my ($self, @filters) = @_;
  100.   push(@{$self->[FILTERS]}, @filters);
  101. }
  102.  
  103. #------------------------------------------------------------------------------
  104.  
  105. sub pop {
  106.   my ($self) = @_;
  107.   my $filter = pop @{$self->[FILTERS]};
  108.   $self->[FILTERS]->[-1]->put($filter->get_pending || []);
  109.   $filter;
  110. }
  111.  
  112. ###############################################################################
  113.  
  114. 1;
  115.  
  116. __END__
  117.  
  118. =head1 NAME
  119.  
  120. POE::Filter::Stackable - POE Multiple Filter Abstraction
  121.  
  122. =head1 SYNOPSIS
  123.  
  124.   $filter = new POE::Filter::Stackable(Filters => [ $filter1, $filter2 ]);
  125.   $filter = new POE::Filter::Stackable;
  126.   $filter->push($filter1, $filter2);
  127.   $filter2 = $filter->pop;
  128.   $filter1 = $filter->shift;
  129.   $filter->unshift($filter1, $filter2);
  130.   $arrayref_for_driver = $filter->put($arrayref_of_data);
  131.   $arrayref_for_driver = $filter->put($single_data_element);
  132.   $arrayref_of_data = $filter->get($arrayref_of_raw_data);
  133.   $arrayref_of_leftovers = $filter->get_pending;
  134.   @filter_type_names = $filter->filter_types;
  135.   @filter_objects = $filter->filters;
  136.  
  137. =head1 DESCRIPTION
  138.  
  139. The Stackable filter allows the use of multiple filters within a
  140. single wheel.  Internally, filters are stored in an array, with array
  141. index 0 being "near" to the wheel's handle and therefore being the
  142. first filter passed through using "get" and the last filter passed
  143. through in "put".  All POE::Filter public methods are implemented as
  144. though data were being passed through a single filter; other program
  145. components do not need to know there are multiple filters.
  146.  
  147. =head1 PUBLIC FILTER METHODS
  148.  
  149. =over 4
  150.  
  151. =item *
  152.  
  153. POE::Filter::Stackable::new( ... )
  154.  
  155. The new() method creates the Stackable filter.  It accepts an optional
  156. parameter "Filters" that specifies an arrayref of initial filters.  If
  157. no filters are given, Stackable will pass data through unchanged; this
  158. is true if there are no filters present at any time.
  159.  
  160. =item *
  161.  
  162. POE::Filter::Stackable::pop()
  163. POE::Filter::Stackable::shift()
  164. POE::Filter::Stackable::push($filter1, $filter2, ...)
  165. POE::Filter::Stackable::unshift($filter1, $filter2...)
  166.  
  167. These methods all function identically to the perl builtin functions
  168. of the same name.  push() and unshift() will return the new number of
  169. filters inside the Stackable filter.
  170.  
  171. =item *
  172.  
  173. POE::Filter::Stackable::filter_types
  174.  
  175. The filter_types() method returns a list of types for the filters
  176. inside the Stackable filter, in order from near to far; for example,
  177. qw(Block HTTPD).
  178.  
  179. =item *
  180.  
  181. POE::Filter::Stackable::filters
  182.  
  183. The filters() method returns a list of the objects inside the
  184. Stackable filter, in order from near to far.
  185.  
  186. =item *
  187.  
  188. See POE::Filter.
  189.  
  190. =back
  191.  
  192. =head1 SEE ALSO
  193.  
  194. POE::Filter; POE::Filter::HTTPD; POE::Filter::Reference;
  195. POE::Filter::Line; POE::Filter::Block; POE::Filter::Stream
  196.  
  197. =head1 BUGS
  198.  
  199. Undoubtedly.  None currently known.
  200.  
  201. =head1 AUTHORS & COPYRIGHTS
  202.  
  203. The Stackable filter was contributed by Dieter Pearcey.  Rocco Caputo
  204. is sure to have had his hands in it.
  205.  
  206. Please see the POE manpage for more information about authors and
  207. contributors.
  208.  
  209. =cut
  210.  
  211.