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   670 use strict;
  3         5  
  3         145  
16 3     3   11 use warnings;
  3         3  
  3         61  
17 3     3   1323 use IO::String;
  3         8492  
  3         2169  
18              
19             our @ISA = qw(IO::String);
20              
21              
22             sub open {
23 9     9 1 237 my $self = shift;
24 9         13 my ($dataref, $mode, $close_callback) = @_;
25 9 50       27 return $self->new(@_) unless ref($self);
26              
27             # check mode
28 9         8 my $read;
29             my $write;
30 9 100       55 if ($mode =~ /^\+?>>?$/) {
    50          
31 4         5 $write = 1;
32 4 50       11 $read = 1 if $mode =~ /^\+/;
33             }
34             elsif ($mode =~ /^\+?<$/) {
35 5         7 $read = 1;
36 5 100       15 $write = 1 if $mode =~ /^\+/;
37             }
38              
39 9         35 $self->SUPER::open($dataref);
40              
41 9         103 *$self->{_cache_read} = $read;
42 9         12 *$self->{_cache_write} = $write;
43 9         14 *$self->{_cache_close_callback} = $close_callback;
44              
45 9 100       25 if ($write) {
46 7 100       26 if ($mode =~ /^\+?>>$/) {
    100          
47             # append
48 2         6 $self->seek(0, 2);
49             }
50             elsif ($mode =~ /^\+?>$/) {
51             # truncate
52 2         7 $self->truncate(0);
53             }
54             }
55              
56 9         62 return $self;
57             }
58              
59             sub close {
60 8     8 0 47 my $self = shift;
61 8         17 delete *$self->{_cache_read};
62 8         12 delete *$self->{_cache_write};
63 8 100       26 *$self->{_cache_close_callback}->($self) if *$self->{_cache_close_callback};
64 8         20 delete *$self->{_cache_close_callback};
65 8         1049 $self->SUPER::close(@_);
66             }
67              
68             sub DESTROY {
69 9     9   1587 my $self = shift;
70 9 50       171 *$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 11 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       16 return $self->SUPER::setpos(@_) unless *$self->{_cache_write};
96 7         27 return $self->SUPER::seek(@_);
97             }
98              
99             sub getline {
100 12     12 0 126 my $self = shift;
101 12 50       32 return undef unless *$self->{_cache_read};
102 12         37 return $self->SUPER::getline(@_);
103             }
104              
105             sub truncate {
106 2     2 0 2 my $self = shift;
107 2 50       6 return undef unless *$self->{_cache_write};
108 2         13 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 1364 my $self = shift;
119 9 100       31 return undef unless *$self->{_cache_write};
120 8         31 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__