File Coverage

blib/lib/Data/Scan.pm
Criterion Covered Total %
statement 27 27 100.0
branch 6 6 100.0
condition 9 11 81.8
subroutine 6 6 100.0
pod 1 1 100.0
total 49 51 96.0


line stmt bran cond sub pod time code
1 1     1   478 use strict;
  1         2  
  1         37  
2 1     1   5 use warnings FATAL => 'all';
  1         1  
  1         104  
3              
4             package Data::Scan;
5              
6             # ABSTRACT: Stackfree arbitrary data scanner
7              
8             our $VERSION = '0.009'; # VERSION
9              
10             our $AUTHORITY = 'cpan:JDDPAUSE'; # AUTHORITY
11              
12 1     1   7 use Moo;
  1         2  
  1         5  
13 1     1   315 use Scalar::Util qw/refaddr reftype/;
  1         11  
  1         58  
14 1     1   6 use Types::Standard qw/ConsumerOf/;
  1         2  
  1         8  
15              
16              
17             has consumer => (
18             is => 'ro',
19             isa => ConsumerOf['Data::Scan::Role::Consumer'],
20             );
21              
22              
23             my $_open;
24             my $_close;
25             my $openaddr = \$_open;
26             my $closeaddr = \$_close;
27              
28              
29             #
30             # Avoid calls to arybase
31             #
32             my $ARRAY_START_INDICE = $[;
33              
34             sub process {
35 1     1 1 148 my ($self) = shift;
36              
37 1         8 my ($consumer, $previous, $inner) = $self->consumer;
38             #
39             # Start
40             #
41 1         6 $consumer->dsstart(@_);
42             #
43             # Loop
44             #
45 1         8 while (@_) {
46             #
47             # First our private thingies
48             #
49 36   100     149 while (@_ && ref $_[$ARRAY_START_INDICE]) {
50 34 100       127 if ($openaddr == refaddr $_[$ARRAY_START_INDICE]) { $consumer->dsopen ((splice @_, $ARRAY_START_INDICE, 2)[-1]) }
  10 100       32  
51 10         31 elsif ($closeaddr == refaddr $_[$ARRAY_START_INDICE]) { $consumer->dsclose((splice @_, $ARRAY_START_INDICE, 2)[-1]) }
52 14         24 else { last }
53             }
54             #
55             # Consumer's dsread() returns eventual inner content
56             #
57             unshift(@_,
58             $openaddr, $previous,
59 36 100 100     128 @{$inner},
  10   50     45  
      66        
60             $closeaddr, $previous
61             ) if (@_ && defined($inner = $consumer->dsread($previous = shift)) && (reftype($inner) // '') eq 'ARRAY')
62             }
63             #
64             # End - return value of consumer's dsend() is what we return
65             #
66 1         4 return $consumer->dsend()
67             }
68              
69              
70             1;
71              
72             __END__