home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / Tee.pm < prev    next >
Encoding:
Perl POD Document  |  2001-03-10  |  8.1 KB  |  380 lines

  1. package IO::Tee;
  2.  
  3. require 5.004;
  4. use strict;
  5. use Carp;
  6. use Symbol;
  7. use IO::Handle;
  8. use IO::File;
  9. use vars qw($VERSION @ISA);
  10. $VERSION = '0.64';
  11. @ISA = 'IO::Handle';
  12.  
  13. # Constructor -- bless array reference into our class
  14.  
  15. sub new
  16. {
  17.     my $class = shift;
  18.     my $self = gensym;
  19.     @{*$self} = map {
  20.         ! ref($_) ? IO::File->new($_)
  21.         : ref($_) eq 'ARRAY' ? IO::File->new(@$_)
  22.         : ref($_) eq 'GLOB' ? bless $_, 'IO::Handle'
  23.         : $_ or return undef } @_;
  24.     bless $self, $class;
  25.     tie *$self, $class, $self;
  26.     return $self;
  27. }
  28.  
  29. # Return a list of all associated handles
  30.  
  31. sub handles
  32. {
  33.     @{*{$_[0]}};
  34. }
  35.  
  36. # Proxy routines for various IO::Handle and IO::File operations
  37.  
  38. sub _method_return_success
  39. {
  40.     my $method = (caller(1))[3];
  41.     $method =~ s/.*:://;
  42.  
  43.     my $self = shift;
  44.     my $ret = 1;
  45.     foreach my $fh (@{*$self}) { undef $ret unless $fh->$method(@_) }
  46.     return $ret;
  47. }
  48.  
  49. sub close        { _method_return_success(@_) }
  50. sub truncate     { _method_return_success(@_) }
  51. sub write        { _method_return_success(@_) }
  52. sub syswrite     { _method_return_success(@_) }
  53. sub format_write { _method_return_success(@_) }
  54. sub fcntl        { _method_return_success(@_) }
  55. sub ioctl        { _method_return_success(@_) }
  56. sub flush        { _method_return_success(@_) }
  57. sub clearerr     { _method_return_success(@_) }
  58. sub seek         { _method_return_success(@_) }
  59.  
  60. sub formline
  61. {
  62.     my $self = shift;
  63.     my $picture = shift;
  64.     local($^A) = $^A;
  65.     local($\) = "";
  66.     formline($picture, @_);
  67.  
  68.     my $ret = 1;
  69.     foreach my $fh (@{*$self}) { undef $ret unless print $fh $^A }
  70.     return $ret;
  71. }
  72.  
  73. sub _state_modify
  74. {
  75.     my $method = (caller(1))[3];
  76.     $method =~ s/.*:://;
  77.     croak "$method values cannot be retrieved collectively" if @_ <= 1;
  78.  
  79.     my $self = shift;
  80.     if (ref $self)
  81.     {
  82.         foreach my $fh (@{*$self}) { $fh->$method(@_) }
  83.     }
  84.     else
  85.     {
  86.         IO::Handle->$method(@_);
  87.     }
  88.     # Note that we do not return any "previous value" here
  89. }
  90.  
  91. sub autoflush                    { _state_modify(@_) }
  92. sub output_field_separator       { _state_modify(@_) }
  93. sub output_record_separator      { _state_modify(@_) }
  94. sub format_page_number           { _state_modify(@_) }
  95. sub format_lines_per_page        { _state_modify(@_) }
  96. sub format_lines_left            { _state_modify(@_) }
  97. sub format_name                  { _state_modify(@_) }
  98. sub format_top_name              { _state_modify(@_) }
  99. sub format_line_break_characters { _state_modify(@_) }
  100. sub format_formfeed              { _state_modify(@_) }
  101.  
  102. sub input_record_separator
  103. {
  104.     my $self = shift;
  105.     my $ret = (ref $self ? ${*$self}[0] : 'IO::Handle')
  106.         ->input_record_separator(@_);
  107.     $ret; # This works around an apparent bug in Perl 5.004_04
  108. }
  109.  
  110. sub input_line_number
  111. {
  112.     my $self = shift;
  113.     my $ret = ${*$self}[0]->input_line_number(@_);
  114.     $ret; # This works around an apparent bug in Perl 5.004_04
  115. }
  116.  
  117. # File handle tying interface
  118.  
  119. sub TIEHANDLE
  120. {
  121.     my ($class, $self) = @_;
  122.     return bless *$self{ARRAY}, $class;
  123. }
  124.  
  125. sub PRINT
  126. {
  127.     my $self = shift;
  128.     my $ret = 1;
  129.     foreach my $fh (@$self) { undef $ret unless print $fh @_ }
  130.     return $ret;
  131. }
  132.  
  133. sub PRINTF
  134. {
  135.     my $self = shift;
  136.     my $fmt = shift;
  137.     my $ret = 1;
  138.     foreach my $fh (@$self) { undef $ret unless printf $fh $fmt, @_ }
  139.     return $ret;
  140. }
  141.  
  142. sub _multiplex_input
  143. {
  144.     my ($self, $input) = @_;
  145.     my $ret = 1;
  146.     if (length $input)
  147.     {
  148.         for (my $i = 1; $i < @$self; ++$i)
  149.         {
  150.             undef $ret unless print {$self->[$i]} $input;
  151.         }
  152.     }
  153.     $ret;
  154. }
  155.  
  156. sub READ
  157. {
  158.     my $self = shift;
  159.     my $bytes = $self->[0]->read(@_);
  160.     $bytes and $self->_multiplex_input(substr($_[0], $_[2], $bytes));
  161.     $bytes;
  162. }
  163.  
  164. sub READLINE
  165. {
  166.     my $self = shift;
  167.     my $infh = $self->[0];
  168.     if (wantarray)
  169.     {
  170.         my @data;
  171.         my $data;
  172.         while (defined($data = <$infh>) and length($data))
  173.         {
  174.             push @data, $data;
  175.             $self->_multiplex_input($data);
  176.         }
  177.         @data;
  178.     }
  179.     else
  180.     {
  181.         my $data = <$infh>;
  182.         defined $data and $self->_multiplex_input($data);
  183.         $data;
  184.     }
  185. }
  186.  
  187. sub GETC
  188. {
  189.     my $self = shift;
  190.     my $data = getc($self->[0]);
  191.     defined $data and $self->_multiplex_input($data);
  192.     $data;
  193. }
  194.  
  195. sub sysread
  196. {
  197.     my $self = shift;
  198.     my $bytes = ${*$self}[0]->sysread(@_);
  199.     $bytes and (\@{*$self})->
  200.         _multiplex_input(substr($_[0], $_[2] || 0, $bytes));
  201.     $bytes;
  202. }
  203.  
  204. sub EOF
  205. {
  206.     my $self = shift;
  207.     return $self->[0]->eof;
  208. }
  209.  
  210. 1;
  211. __END__
  212.  
  213. =head1 NAME
  214.  
  215. IO::Tee - Multiplex output to multiple output handles
  216.  
  217. =head1 SYNOPSIS
  218.  
  219.     use IO::Tee;
  220.  
  221.     $tee = IO::Tee->new($handle1, $handle2);
  222.     print $tee "foo", "bar";
  223.     my $input = <$tee>;
  224.  
  225. =head1 DESCRIPTION
  226.  
  227. C<IO::Tee> objects can be used to multiplex input and output in two
  228. different ways.  The first way is to multiplex output to zero or more
  229. output handles.  The C<IO::Tee> constructor, given a list of output
  230. handles, returns a tied handle that can be written to.  When written
  231. to (using print or printf), the C<IO::Tee> object multiplexes the
  232. output to the list of handles originally passed to the constructor.
  233. As a shortcut, you can also directly pass a string or an array
  234. reference to the constructor, in which case C<IO::File::new> is called
  235. for you with the specified argument or arguments.
  236.  
  237. The second way is to multiplex input from one input handle to zero or
  238. more output handles as it is being read.  The C<IO::Tee> constructor,
  239. given an input handle followed by a list of output handles, returns a
  240. tied handle that can be read from as well as written to.  When written
  241. to, the C<IO::Tee> object multiplexes the output to all handles passed
  242. to the constructor, as described in the previous paragraph.  When read
  243. from, the C<IO::Tee> object reads from the input handle given as the
  244. first argument to the C<IO::Tee> constructor, then writes any data
  245. read to the output handles given as the remaining arguments to the
  246. constructor.
  247.  
  248. The C<IO::Tee> class supports certain C<IO::Handle> and C<IO::File>
  249. methods related to input and output.  In particular, the following
  250. methods will iterate themselves over all handles associated with the
  251. C<IO::Tee> object, and return TRUE indicating success if and only if
  252. all associated handles returned TRUE indicating success:
  253.  
  254. =over 4
  255.  
  256. =item close
  257.  
  258. =item truncate
  259.  
  260. =item write
  261.  
  262. =item syswrite
  263.  
  264. =item format_write
  265.  
  266. =item formline
  267.  
  268. =item fcntl
  269.  
  270. =item ioctl
  271.  
  272. =item flush
  273.  
  274. =item clearerr
  275.  
  276. =item seek
  277.  
  278. =back
  279.  
  280. The following methods perform input multiplexing as described above:
  281.  
  282. =over 4
  283.  
  284. =item read
  285.  
  286. =item sysread
  287.  
  288. =item readline
  289.  
  290. =item getc
  291.  
  292. =item gets
  293.  
  294. =item eof
  295.  
  296. =item getline
  297.  
  298. =item getlines
  299.  
  300. =back
  301.  
  302. The following methods can be used to set (but not retrieve) the
  303. current values of output-related state variables on all associated
  304. handles:
  305.  
  306. =over 4
  307.  
  308. =item autoflush
  309.  
  310. =item output_field_separator
  311.  
  312. =item output_record_separator
  313.  
  314. =item format_page_number
  315.  
  316. =item format_lines_per_page
  317.  
  318. =item format_lines_left
  319.  
  320. =item format_name
  321.  
  322. =item format_top_name
  323.  
  324. =item format_line_break_characters
  325.  
  326. =item format_formfeed
  327.  
  328. =back
  329.  
  330. The following methods are directly passed on to the input handle given
  331. as the first argument to the C<IO::Tee> constructor:
  332.  
  333. =over 4
  334.  
  335. =item input_record_separator
  336.  
  337. =item input_line_number
  338.  
  339. =back
  340.  
  341. Note that the return value of input multiplexing methods (such as
  342. C<print>) is always the return value of the input action, not the
  343. return value of subsequent output actions.  In particular, no error is
  344. indicated by the return value if the input action itself succeeds but
  345. subsequent output multiplexing fails.
  346.  
  347. =head1 EXAMPLE
  348.  
  349.     use IO::Tee;
  350.     use IO::File;
  351.  
  352.     my $tee = new IO::Tee(\*STDOUT,
  353.         new IO::File(">tt1.out"), ">tt2.out");
  354.  
  355.     print join(' ', $tee->handles), "\n";
  356.  
  357.     for (1..10) { print $tee $_, "\n" }
  358.     for (1..10) { $tee->print($_, "\n") }
  359.     $tee->flush;
  360.  
  361.     $tee = new IO::Tee('</etc/passwd', \*STDOUT);
  362.     my @lines = <$tee>;
  363.     print scalar(@lines);
  364.  
  365. =head1 AUTHOR
  366.  
  367. Chung-chieh Shan, ken@digitas.harvard.edu
  368.  
  369. =head1 COPYRIGHT
  370.  
  371. Copyright (c) 1998-2001 Chung-chieh Shan.  All rights reserved.
  372. This program is free software; you can redistribute it and/or
  373. modify it under the same terms as Perl itself.
  374.  
  375. =head1 SEE ALSO
  376.  
  377. L<perlfunc>, L<IO::Handle>, L<IO::File>.
  378.  
  379. =cut
  380.