File Coverage

blib/lib/PerlIO/via/Limit.pm
Criterion Covered Total %
statement 50 50 100.0
branch 16 18 88.8
condition 1 3 33.3
subroutine 11 11 100.0
pod 1 3 33.3
total 79 85 92.9


line stmt bran cond sub pod time code
1             package PerlIO::via::Limit;
2              
3 6     6   192487 use strict;
  6         15  
  6         322  
4 6     6   32 use warnings;
  6         11  
  6         274  
5 6     6   33 use vars qw($VERSION);
  6         16  
  6         624  
6             $VERSION = '0.04';
7              
8             our @ISA;
9             unshift @ISA, qw(Class::Data::Inheritable);
10              
11 6     6   6842 use Exception::Class ('PerlIO::via::Limit::Exception');
  6         124020  
  6         118  
12              
13             __PACKAGE__->mk_classdata('length');
14             __PACKAGE__->mk_classdata('sensitive');
15              
16             sub import {
17 6     6   50 my ($class, %params) = @_;
18 6         4948 $class->$_( $params{$_} ) for keys %params;
19             }
20              
21             my $create_count = 0;
22             sub create {
23 17     17 1 16684 my ($class, $len, $new_class) = @_;
24              
25 17 50       198 $new_class = sprintf('%s::_%s', __PACKAGE__, ++$create_count)
26             unless( defined $new_class );
27              
28 6     6   2569 no strict 'refs';
  6         18  
  6         2965  
29 17         29 @{"$new_class\::ISA"} = __PACKAGE__;
  17         386  
30              
31 17         335 $new_class->length($len);
32 17         730 return $new_class;
33             }
34              
35             sub PUSHED {
36 22     22 0 22025 my ($class, $mode, $fh) = @_;
37 22         1685 return bless {current => 0, reached => 0}, $class;
38             }
39              
40             sub FILL {
41 36     36 0 595 my ($obj, $fh) = @_;
42              
43 36 100       151 if( $obj->{reached} ){
44 16 100       60 if( $obj->sensitive ){
45 2         35 PerlIO::via::Limit::Exception
46             ->throw( error => "$fh is trying to read exceeding the limit." );
47             }
48 14         147 return undef;
49             }
50              
51 20         421 my $buf = <$fh>;
52              
53 20 100       49 if( defined $buf ){
54 16         35 $obj->{current} += CORE::length $buf;
55 16         69 $obj->_check(\$buf);
56             }
57              
58 20         110 return $buf;
59             }
60              
61             sub WRITE {
62 8     8   117 my ($obj, $buf, $fh) = @_;
63 8 50 33     82 return 0 if( $obj->{reached} or ! defined $buf );
64              
65 8         19 $obj->{current} += CORE::length $buf;
66 8         113 $obj->_check(\$buf);
67              
68 8         92 print $fh $buf;
69              
70 8 100       20 if( $obj->{reached} ){
71 4 100       21 if( $obj->sensitive ){
72 2         167 PerlIO::via::Limit::Exception
73             ->throw( error => "$fh is trying to write exceeding the limit." );
74             }
75             }
76              
77 6         55 return CORE::length $buf;
78             }
79              
80             sub _check {
81 24     24   93 my ($obj, $ref_buf) = @_;
82 24 100       69 if( defined(my $len = $obj->length) ){
83 20         165 my $over = $obj->{current} - $len;
84 20 100       52 if( 0 <= $over ){
85 16         24 $obj->{reached} = 1;
86 16         88 substr($$ref_buf, $over * -1, $over, q{});
87             # another expression:
88             # $$ref_buf = substr( $$ref_buf, 0, CORE::length($$ref_buf) - $over );
89             }
90             }
91             }
92              
93              
94             1;
95             __END__