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   338 use strict;
  1         1  
  1         26  
2 1     1   3 use warnings FATAL => 'all';
  1         1  
  1         44  
3              
4             package Data::Scan;
5              
6             # ABSTRACT: Stackfree arbitrary data scanner
7              
8             our $VERSION = '0.007'; # VERSION
9              
10             our $AUTHORITY = 'cpan:JDDPAUSE'; # AUTHORITY
11              
12 1     1   4 use Moo;
  1         1  
  1         4  
13 1     1   166 use Scalar::Util qw/refaddr reftype/;
  1         1  
  1         55  
14 1     1   3 use Types::Standard qw/ConsumerOf/;
  1         1  
  1         7  
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 109 my ($self) = shift;
36              
37 1         6 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     121 while (@_ && ref $_[$ARRAY_START_INDICE]) {
50 34 100       95 if ($openaddr == refaddr $_[$ARRAY_START_INDICE]) { $consumer->dsopen ((splice @_, $ARRAY_START_INDICE, 2)[-1]) }
  10 100       34  
51 10         24 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     103 @{$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__