File Coverage

blib/lib/XML/LibXML/NodeList/Iterator.pm
Criterion Covered Total %
statement 78 101 77.2
branch 18 34 52.9
condition 2 9 22.2
subroutine 15 22 68.1
pod 13 13 100.0
total 126 179 70.3


line stmt bran cond sub pod time code
1             # $Id: Iterator.pm,v 1.1.1.1 2002/11/08 17:18:36 phish Exp $
2             #
3             package XML::LibXML::NodeList::Iterator;
4             $XML::LibXML::NodeList::Iterator::VERSION = '1.06';
5 2     2   132266 use strict;
  2         12  
  2         49  
6 2     2   9 use warnings;
  2         3  
  2         48  
7              
8 2     2   400 use XML::NodeFilter qw(:results);
  2         1476  
  2         201  
9              
10 2     2   13 use vars qw($VERSION);
  2         3  
  2         236  
11             $VERSION = "1.03";
12              
13             ## no critic
14             use overload
15 0     0   0 '++' => sub { $_[0]->nextNode(); $_[0]; },
  0         0  
16 0     0   0 '--' => sub { $_[0]->previousNode(); $_[0] },
  0         0  
17 0 0   0   0 '<>' => sub { return wantarray ? $_[0]->_get_all : $_[0]->nextNode(); },
18 2     2   10 ;
  2         5  
  2         15  
19             ## use critic
20              
21             sub new
22             {
23 9     9 1 4380 my $class = shift;
24 9         16 my $list = shift;
25 9         10 my $self = undef;
26 9 50       20 if ( defined $list )
27             {
28 9         19 $self = bless [ $list, -1, [], ], $class;
29             }
30              
31 9         18 return $self;
32             }
33              
34             sub set_filter
35             {
36 0     0 1 0 my $self = shift;
37 0         0 $self->[2] = [@_];
38             }
39              
40             sub add_filter
41             {
42 1     1 1 44 my $self = shift;
43 1         2 push @{ $self->[2] }, @_;
  1         3  
44             }
45              
46             # helper function.
47             sub accept_node
48             {
49 29     29 1 33 foreach ( @{ $_[0][2] } )
  29         47  
50             {
51 1         4 my $r = $_->accept_node( $_[1] );
52 1 50       8 return $r if $r;
53             }
54              
55             # no filters or all decline ...
56 29         54 return FILTER_ACCEPT;
57             }
58              
59             sub first
60             {
61 2     2 1 8 $_[0][1] = 0;
62 2         4 my $s = scalar( @{ $_[0][0] } );
  2         3  
63 2         5 while ( $_[0][1] < $s )
64             {
65 2 50       19 last if $_[0]->accept_node( $_[0][0][ $_[0][1] ] ) == FILTER_ACCEPT;
66 0         0 $_[0][1]++;
67             }
68 2 50       5 return undef if $_[0][1] == $s;
69 2         5 return $_[0][0][ $_[0][1] ];
70             }
71              
72             sub last
73             {
74 3     3 1 10 my $i = scalar( @{ $_[0][0] } ) - 1;
  3         7  
75 3         21 while ( $i >= 0 )
76             {
77 3 50       7 if ( $_[0]->accept_node( $_[0][0][$i] ) == FILTER_ACCEPT )
78             {
79 3         5 $_[0][1] = $i;
80 3         4 last;
81             }
82 0         0 $i--;
83             }
84              
85 3 50       7 if ( $i < 0 )
86             {
87             # this costs a lot, but is more safe
88 0         0 return $_[0]->first;
89             }
90 3         6 return $_[0][0][$i];
91             }
92              
93             sub current
94             {
95 14 50 33 14 1 58 if ( $_[0][1] >= 0 || $_[0][1] < scalar @{ $_[0][0] } )
  0         0  
96             {
97 14         47 return $_[0][0][ $_[0][1] ];
98             }
99 0         0 return undef;
100             }
101              
102             sub index
103             {
104 0 0 0 0 1 0 if ( $_[0][1] >= 0 || $_[0][1] < scalar @{ $_[0][0] } )
  0         0  
105             {
106 0         0 return $_[0][1];
107             }
108 0         0 return undef;
109             }
110              
111 9     9 1 42 sub next { return $_[0]->nextNode(); }
112 0     0 1 0 sub previous { return $_[0]->previousNode(); }
113              
114             sub nextNode
115             {
116 23     23 1 69 my $nlen = scalar @{ $_[0][0] };
  23         68  
117 23 100       40 if ( $nlen <= ( $_[0][1] + 1 ) )
118             {
119 5         10 return undef;
120             }
121 18         24 my $i = $_[0][1];
122 18 100       28 $i = -1 if $i < 0; # assure that we end up with the first
123             # element in the first iteration
124 18         20 while (1)
125             {
126 18         19 $i++;
127 18 50       25 return undef if $i >= $nlen;
128 18 50       28 if ( $_[0]->accept_node( $_[0][0]->[$i] ) == FILTER_ACCEPT )
129             {
130 18         29 $_[0][1] = $i;
131 18         37 last;
132             }
133             }
134 18         33 return $_[0][0]->[ $_[0][1] ];
135             }
136              
137             sub previousNode
138             {
139 8 100   8 1 35 if ( $_[0][1] <= 0 )
140             {
141 2         3 return undef;
142             }
143 6         7 my $i = $_[0][1];
144 6         7 while (1)
145             {
146 6         7 $i--;
147 6 50       8 return undef if $i < 0;
148 6 50       12 if ( $_[0]->accept_node( $_[0][0]->[$i] ) == FILTER_ACCEPT )
149             {
150 6         9 $_[0][1] = $i;
151 6         7 last;
152             }
153             }
154 6         8 return $_[0][0][ $_[0][1] ];
155             }
156              
157             sub iterate
158             {
159 2     2 1 14 my $self = shift;
160 2         4 my $funcref = shift;
161 2         2 my $rv;
162              
163 2 50 33     11 return () unless defined $funcref && ref($funcref) eq 'CODE';
164              
165 2         3 $self->[1] = -1; # first element
166 2         5 while ( my $node = $self->next )
167             {
168 6         24 $rv = $funcref->( $self, $node );
169             }
170 2         3 return $rv;
171             }
172              
173             # helper function for the <> operator
174             # returns all nodes that have not yet been accessed
175             sub _get_all
176             {
177 0     0     my $self = shift;
178 0           my @retval = ();
179 0           my $node;
180 0           while ( $node = $self->next() )
181             {
182 0           push @retval, $node;
183             }
184 0           return @retval;
185             }
186              
187             1;
188              
189             __END__