File Coverage

blib/lib/Tie/Array/Pack.pm
Criterion Covered Total %
statement 83 93 89.2
branch 26 50 52.0
condition 1 2 50.0
subroutine 19 21 90.4
pod n/a
total 129 166 77.7


line stmt bran cond sub pod time code
1             package Tie::Array::Pack;
2             #
3             # $Id: Pack.pm,v 0.2 2006/12/22 03:20:22 dankogai Exp $
4             #
5 2     2   76178 use 5.008001;
  2         9  
  2         84  
6 2     2   11 use strict;
  2         5  
  2         71  
7 2     2   17 use warnings;
  2         9  
  2         149  
8             our $VERSION = sprintf "%d.%02d", q$Revision: 0.2 $ =~ /(\d+)/g;
9 2     2   12 use Carp;
  2         2  
  2         214  
10              
11             # we don't need Tie::Array anymore -- all methods implemented!
12             # use base 'Tie::Array';
13 2     2   2146 use bytes ();
  2         21  
  2         490  
14              
15             our $DEBUG = 0;
16              
17 0     0   0 sub DESTROY { } # no-op
18              
19             sub TIEARRAY {
20 18     18   7882 my $class = shift;
21 18         42 my $fmt = shift;
22 18   50     128 my $empty = shift || 0;
23 18         45 my $size = eval { bytes::length( pack( $fmt, $empty ) ) };
  18         110  
24 18 50       3869 croak $@ if $@;
25 18         178 bless {
26             str => '',
27             fmt => $fmt,
28             size => $size,
29             empty => $empty
30             };
31             }
32              
33             sub FETCH {
34 2844 50   2844   14013 $DEBUG and warn sprintf "%s->FETCH(%d)", @_;
35 2844         14058 unpack( $_[0]->{fmt},
36             substr( $_[0]->{str}, $_[0]->{size} * $_[1], $_[0]->{size} ) );
37             }
38              
39             sub FETCHSIZE {
40 2268 50   2268   148205 $DEBUG and warn sprintf( "%s->FETCHSIZE", $_[0] );
41 2     2   1909 use integer;
  2         20  
  2         11  
42 2268         5661 bytes::length( $_[0]->{str} ) / $_[0]->{size};
43             }
44              
45             sub STORE {
46 144     144   218 my ( $this, $index, $value ) = @_;
47 144 50       260 $DEBUG and warn "$this->STORE($index, $value)";
48 144 50       218 my $retval =
49             $this->FETCHSIZE - $index < 1
50             ? $this->STORESIZE( $index + 1 )
51             : $value;
52 144         1529 substr(
53             $this->{str}, $this->{size} * $index,
54             $this->{size}, pack( $this->{fmt}, $value )
55             );
56             }
57              
58             sub STORESIZE {
59 36     36   71 my ( $this, $count ) = @_;
60 36 50       80 $DEBUG and warn "$this->STORESIZE($count)";
61 36 50       89 return $this->EXTEND($count) if $this->FETCHSIZE < $count;
62 36 100       195 if ( $this->FETCHSIZE > $count ) {
63 18         117 substr( $this->{str}, $this->{size} * $count, $this->{size}, '' );
64             }
65 36         116 return $count;
66             }
67              
68             sub EXISTS {
69 0     0   0 my ( $this, $key ) = @_;
70 0 0       0 $DEBUG and warn "$this->EXISTS($key)";
71 0         0 return $this->FETCHSIZE > $key;
72             }
73              
74             sub EXTEND {
75 18     18   39 my ( $this, $count ) = @_;
76 18 50       46 $DEBUG and warn "$this->EXTEND($count)";
77 18         46 my $extend = $count - $this->FETCHSIZE;
78 18 50       117 if ( $extend > 0 ) {
79 18         102 $this->{str} .= pack( $this->{fmt}, $this->{empty} ) x $extend;
80 18         67 $this->STORESIZE($count);
81             }
82 18         92 return undef;
83             }
84              
85             sub DELETE {
86 18     18   35 my ( $this, $index ) = @_;
87 18 50       51 $DEBUG and warn "$this->DELETE($index)";
88 18         71 substr( $this->{str}, $this->{size} * $index, $this->{size}, '' );
89             }
90              
91             sub CLEAR {
92 18     18   8088 my ( $this, $index ) = @_;
93 18 50       58 $DEBUG and warn "$this->CLEAR";
94 18         100 $this->{str} = '';
95             }
96              
97             sub PUSH { # append
98 18     18   31 my $this = shift;
99 18 50       141 if ($DEBUG) {
100 0         0 local ($") = ",";
101 0         0 warn "$this->PUSH(@_)";
102             }
103 18         142 $this->{str} .= pack( $this->{fmt} x @_, @_ );
104             }
105              
106             sub UNSHIFT { # prepend
107 18     18   28 my $this = shift;
108 18 50       55 if ($DEBUG) {
109 0         0 local ($") = ",";
110 0         0 warn "$this->UNSHIFT(@_)";
111             }
112 18         149 $this->{str} = pack( $this->{fmt} x @_, @_ ) . $this->{str};
113             }
114              
115             sub POP {
116 18     18   30 my $this = shift;
117 18 50       58 $DEBUG and warn "$this->POP";
118 18         27 my $val;
119 18         43 my $newsize = $this->FETCHSIZE - 1;
120 18 50       105 if ( $newsize >= 0 ) {
121 18         43 $val = $this->FETCH($newsize);
122 18         48 $this->STORESIZE($newsize);
123             }
124 18         54 $val;
125             }
126              
127             sub SHIFT {
128 18     18   41 my $this = shift;
129 18 50       57 $DEBUG and warn "$this->SHIFT";
130 18         29 my $val;
131 18         189 my $newsize = $this->FETCHSIZE - 1;
132 18 50       115 if ( $newsize >= 0 ) {
133 18         39 $val = $this->FETCH(0);
134 18         71 $this->DELETE(0);
135             }
136 18         49 $val;
137             }
138              
139             sub SPLICE {
140 72     72   104 my $this = shift;
141 72 50       184 if ($DEBUG) {
142 0         0 local ($") = ",";
143 0         0 warn "$this->SPLICE(@_)";
144             }
145 72 50       182 my $off = (@_) ? shift: 0;
146 72 50       155 $off += $this->FETCHSIZE if ( $off < 0 );
147 72 100       190 my $len = (@_) ? shift: $this->FETCHSIZE - $off;
148 72 50       332 $len += $this->FETCHSIZE - $off if $len < 0;
149 72         426 my @result = unpack(
150             $this->{fmt} . $len,
151             substr( $this->{str}, $off * $this->{size}, $len * $this->{size} )
152             );
153 72         341 substr(
154             $this->{str},
155             $off * $this->{size},
156             $len * $this->{size},
157             pack( $this->{fmt} x @_, @_ )
158             );
159 72 50       405 return wantarray ? @result : pop @result;
160             }
161              
162             1;
163             __END__