File Coverage

blib/lib/Cache/IOString.pm
Criterion Covered Total %
statement 47 59 79.6
branch 21 36 58.3
condition n/a
subroutine 10 14 71.4
pod 2 10 20.0
total 80 119 67.2


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Cache::IOString - wrapper for IO::String to use in Cache implementations
4              
5             =head1 DESCRIPTION
6              
7             This module implements a derived class of IO::String that handles access
8             modes and allows callback on close. It is for use by Cache implementations
9             and should not be used directly.
10              
11             =cut
12             package Cache::IOString;
13              
14             require 5.006;
15 3     3   860 use strict;
  3         91  
  3         426  
16 3     3   17 use warnings;
  3         7  
  3         77  
17 3     3   4222 use IO::String;
  3         25950  
  3         4262  
18              
19             our @ISA = qw(IO::String);
20              
21              
22             sub open {
23 9     9 1 455 my $self = shift;
24 9         21 my ($dataref, $mode, $close_callback) = @_;
25 9 50       32 return $self->new(@_) unless ref($self);
26              
27             # check mode
28 9         13 my $read;
29             my $write;
30 9 100       64 if ($mode =~ /^\+?>>?$/) {
    50          
31 4         7 $write = 1;
32 4 50       19 $read = 1 if $mode =~ /^\+/;
33             }
34             elsif ($mode =~ /^\+?<$/) {
35 5         56 $read = 1;
36 5 100       24 $write = 1 if $mode =~ /^\+/;
37             }
38              
39 9         61 $self->SUPER::open($dataref);
40              
41 9         138 *$self->{_cache_read} = $read;
42 9         29 *$self->{_cache_write} = $write;
43 9         19 *$self->{_cache_close_callback} = $close_callback;
44              
45 9 100       28 if ($write) {
46 7 100       44 if ($mode =~ /^\+?>>$/) {
    100          
47             # append
48 2         10 $self->seek(0, 2);
49             }
50             elsif ($mode =~ /^\+?>$/) {
51             # truncate
52 2         11 $self->truncate(0);
53             }
54             }
55              
56 9         269 return $self;
57             }
58              
59             sub close {
60 8     8 0 54 my $self = shift;
61 8         24 delete *$self->{_cache_read};
62 8         18 delete *$self->{_cache_write};
63 8 100       48 *$self->{_cache_close_callback}->($self) if *$self->{_cache_close_callback};
64 8         32 delete *$self->{_cache_close_callback};
65 8         58 $self->SUPER::close(@_);
66             }
67              
68             sub DESTROY {
69 9     9   2912 my $self = shift;
70 9 50       321 *$self->{_cache_close_callback}->($self) if *$self->{_cache_close_callback};
71             }
72              
73             sub pad {
74 0     0 1 0 my $self = shift;
75 0 0       0 return undef unless *$self->{_cache_write};
76 0         0 return $self->SUPER::pad(@_);
77             }
78              
79             sub getc {
80 0     0 0 0 my $self = shift;
81 0 0       0 return undef unless *$self->{_cache_read};
82 0         0 return $self->SUPER::getc(@_);
83             }
84              
85             sub ungetc {
86 0     0 0 0 my $self = shift;
87 0 0       0 return undef unless *$self->{_cache_read};
88 0         0 return $self->SUPER::ungetc(@_);
89             }
90              
91             sub seek {
92 7     7 0 20 my $self = shift;
93             # call setpos if not writing to ensure a seek past the end doesn't extend
94             # the string. Probably should really return undef in that situation.
95 7 50       30 return $self->SUPER::setpos(@_) unless *$self->{_cache_write};
96 7         44 return $self->SUPER::seek(@_);
97             }
98              
99             sub getline {
100 12     12 0 317 my $self = shift;
101 12 50       38 return undef unless *$self->{_cache_read};
102 12         52 return $self->SUPER::getline(@_);
103             }
104              
105             sub truncate {
106 2     2 0 5 my $self = shift;
107 2 50       11 return undef unless *$self->{_cache_write};
108 2         19 return $self->SUPER::truncate(@_);
109             }
110              
111             sub read {
112 0     0 0 0 my $self = shift;
113 0 0       0 return undef unless *$self->{_cache_read};
114 0         0 return $self->SUPER::read(@_);
115             }
116              
117             sub write {
118 9     9 0 2631 my $self = shift;
119 9 100       51 return undef unless *$self->{_cache_write};
120 8         56 return $self->SUPER::write(@_);
121             }
122              
123             *GETC = \&getc;
124             *READ = \&read;
125             *WRITE = \&write;
126             *SEEK = \&seek;
127             *CLOSE = \&close;
128              
129              
130             1;
131             __END__