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 / RecordBlock.pm < prev    next >
Encoding:
Perl POD Document  |  2003-11-21  |  5.1 KB  |  201 lines

  1. # 2001/01/25 shizukesa@pobox.com
  2.  
  3. package POE::Filter::RecordBlock;
  4.  
  5. use strict;
  6.  
  7. use vars qw($VERSION);
  8. $VERSION = do {my@r=(q$Revision: 1.4 $=~/\d+/g);sprintf"%d."."%04d"x$#r,@r};
  9.  
  10. use Carp qw(croak);
  11.  
  12. sub BLOCKSIZE () { 0 };
  13. sub GETBUFFER () { 1 };
  14. sub PUTBUFFER () { 2 };
  15. sub CHECKPUT  () { 3 };
  16.  
  17. #------------------------------------------------------------------------------
  18.  
  19. sub new {
  20.   my $type = shift;
  21.  
  22.   croak "$type must be given an even number of parameters" if @_ & 1;
  23.   my %params = @_;
  24.  
  25.   croak "BlockSize must be greater than 0" if
  26.     !defined($params{BlockSize}) || ($params{BlockSize} < 1);
  27.  
  28.   my $self = bless [$params{BlockSize}, [], [], $params{CheckPut}], $type;
  29. }
  30.  
  31. #------------------------------------------------------------------------------
  32.  
  33. sub get {
  34.   my ($self, $data) = @_;
  35.   my @result;
  36.   push @{$self->[GETBUFFER]}, @$data;
  37.   while (@{$self->[GETBUFFER]} >= $self->[BLOCKSIZE]) {
  38.     push @result, [ splice @{$self->[GETBUFFER]}, 0, $self->[BLOCKSIZE] ];
  39.   }
  40.   \@result;
  41. }
  42.  
  43. #------------------------------------------------------------------------------
  44. # 2001-07-27 RCC: Add get_one_start() and get_one() to correct filter
  45. # changing and make input flow control possible.
  46.  
  47. sub get_one_start {
  48.   my ($self, $data) = @_;
  49.   push @{$self->[GETBUFFER]}, @$data;
  50. }
  51.  
  52. sub get_one {
  53.   my $self = shift;
  54.  
  55.   return [ ] unless @{$self->[GETBUFFER]} >= $self->[BLOCKSIZE];
  56.   return [ splice @{$self->[GETBUFFER]}, 0, $self->[BLOCKSIZE] ];
  57. }
  58.  
  59. #------------------------------------------------------------------------------
  60.  
  61. sub put {
  62.   my ($self, $data) = @_;
  63.   my @result;
  64.  
  65.   if ($self->[CHECKPUT]) {
  66.     foreach (@$data) {
  67.       push @{$self->[PUTBUFFER]}, @$_;
  68.     }
  69.     while (@{$self->[PUTBUFFER]} >= $self->[BLOCKSIZE]) {
  70.       push @result, splice @{$self->[GETBUFFER]}, 0, $self->[BLOCKSIZE];
  71.     }
  72.   }
  73.   else {
  74.     push @result, splice(@{$self->[PUTBUFFER]}, 0);
  75.     foreach (@$data) {
  76.       push @result, @$_;
  77.     }
  78.   }
  79.   \@result;
  80. }
  81.  
  82. #------------------------------------------------------------------------------
  83.  
  84. sub get_pending {
  85.   my $self = shift;
  86.   return undef unless @{$self->[GETBUFFER]};
  87.   return [ @{$self->[GETBUFFER]} ];
  88. }
  89.  
  90. #------------------------------------------------------------------------------
  91.  
  92. sub put_pending {
  93.   my ($self) = @_;
  94.   return undef unless $self->[CHECKPUT];
  95.   return undef unless @{$self->[PUTBUFFER]};
  96.   return [ @{$self->[PUTBUFFER]} ];
  97. }
  98.  
  99. #------------------------------------------------------------------------------
  100.  
  101. sub blocksize {
  102.   my ($self, $size) = @_;
  103.   if (defined($size) && ($size > 0)) {
  104.     $self->[BLOCKSIZE] = $size;
  105.   }
  106.   $self->[BLOCKSIZE];
  107. }
  108.  
  109. #------------------------------------------------------------------------------
  110.  
  111. sub checkput {
  112.   my ($self, $val) = @_;
  113.   if (defined($val)) {
  114.     $self->[CHECKPUT] = $val;
  115.   }
  116.   $self->[CHECKPUT];
  117. }
  118.  
  119. ###############################################################################
  120.  
  121. 1;
  122.  
  123. __END__
  124.  
  125. =head1 NAME
  126.  
  127. POE::Filter::RecordBlock - POE Record Block Abstraction
  128.  
  129. =head1 SYNOPSIS
  130.  
  131.   $filter = new POE::Filter::RecordBlock( BlockSize => 4 );
  132.   $arrayref_of_arrayrefs = $filter->get($arrayref_of_raw_data);
  133.   $arrayref_of_raw_chunks = $filter->put($arrayref_of_arrayrefs);
  134.   $arrayref_of_raw_chunks = $filter->put($single_arrayref);
  135.   $arrayref_of_leftovers = $filter->get_pending;
  136.   $arrayref_of_leftovers = $filter->put_pending;
  137.  
  138. =head1 DESCRIPTION
  139.  
  140. RecordBlock translates between streams of B<records> and blocks of
  141. B<records>.  In other words, it combines a number of received records
  142. into frames (array references), and it breaks frames back into streams
  143. of records in preparation for transmitting.
  144.  
  145. A BlockSize parameter must be specified when the filter is
  146. constructed.  It determines how many records are framed into a block,
  147. and it can be changed at runtime.  Checking put() for proper block
  148. sizes is optional and can be either passed as a parameter to the new()
  149. method or changed at runtime.
  150.  
  151. Extra records are held until enough records arrive to complete a
  152. block.
  153.  
  154. =head1 PUBLIC FILTER METHODS
  155.  
  156. =over 4
  157.  
  158. =item *
  159.  
  160. POE::Filter::RecordBlock::new
  161.  
  162. The new() method takes at least one mandatory argument, the BlockSize
  163. parameter.  It must be defined and greater than zero.  The CheckPut
  164. parameter is optional, but if it contains a true value, "put"
  165. blocksize checking is turned on.  Note that if this is the case,
  166. flushing pending records to be put is your responsibility (see
  167. put_pending()).
  168.  
  169. =item *
  170.  
  171. POE::Filter::RecordBlock::put_pending
  172.  
  173. The put_pending() method returns an arrayref of any records that are
  174. waiting to be sent.
  175.  
  176. =item *
  177.  
  178. See POE::Filter.
  179.  
  180. =back
  181.  
  182. =head1 SEE ALSO
  183.  
  184. POE::Filter; POE::Filter::Stackable; POE::Filter::HTTPD;
  185. POE::Filter::Reference; POE::Filter::Line; POE::Filter::Block;
  186. POE::Filter::Stream
  187.  
  188. =head1 BUGS
  189.  
  190. Undoubtedly.
  191.  
  192. =head1 AUTHORS & COPYRIGHTS
  193.  
  194. The RecordBlock filter was contributed by Dieter Pearcey.  Rocco
  195. Caputo is sure to have had his hands in it.
  196.  
  197. Please see the POE manpage for more information about authors and
  198. contributors.
  199.  
  200. =cut
  201.