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   325 use strict;
  1         1  
  1         27  
2 1     1   3 use warnings FATAL => 'all';
  1         1  
  1         45  
3              
4             package Data::Scan;
5              
6             # ABSTRACT: Stackfree arbitrary data scanner
7              
8             our $VERSION = '0.008'; # VERSION
9              
10             our $AUTHORITY = 'cpan:JDDPAUSE'; # AUTHORITY
11              
12 1     1   3 use Moo;
  1         1  
  1         3  
13 1     1   165 use Scalar::Util qw/refaddr reftype/;
  1         2  
  1         45  
14 1     1   4 use Types::Standard qw/ConsumerOf/;
  1         0  
  1         6  
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 125 my ($self) = shift;
36              
37 1         7 my ($consumer, $previous, $inner) = $self->consumer;
38             #
39             # Start
40             #
41 1         4 $consumer->dsstart(@_);
42             #
43             # Loop
44             #
45 1         3 while (@_) {
46             #
47             # First our private thingies
48             #
49 36   100     122 while (@_ && ref $_[$ARRAY_START_INDICE]) {
50 34 100       96 if ($openaddr == refaddr $_[$ARRAY_START_INDICE]) { $consumer->dsopen ((splice @_, $ARRAY_START_INDICE, 2)[-1]) }
  10 100       35  
51 10         23 elsif ($closeaddr == refaddr $_[$ARRAY_START_INDICE]) { $consumer->dsclose((splice @_, $ARRAY_START_INDICE, 2)[-1]) }
52 14         13 else { last }
53             }
54             #
55             # Consumer's dsread() returns eventual inner content
56             #
57             unshift(@_,
58             $openaddr, $previous,
59 36 100 100     98 @{$inner},
  10   50     36  
      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         3 return $consumer->dsend()
67             }
68              
69              
70             1;
71              
72             __END__