Data-Scan
view release on metacpan or search on metacpan
lib/Data/Scan.pm view on Meta::CPAN
use strict;
use warnings FATAL => 'all';
package Data::Scan;
# ABSTRACT: Stackfree arbitrary data scanner
our $VERSION = '0.009'; # VERSION
our $AUTHORITY = 'cpan:JDDPAUSE'; # AUTHORITY
use Moo;
use Scalar::Util qw/refaddr reftype/;
use Types::Standard qw/ConsumerOf/;
has consumer => (
is => 'ro',
isa => ConsumerOf['Data::Scan::Role::Consumer'],
);
my $_open;
my $_close;
my $openaddr = \$_open;
my $closeaddr = \$_close;
#
# Avoid calls to arybase
#
my $ARRAY_START_INDICE = $[;
sub process {
my ($self) = shift;
my ($consumer, $previous, $inner) = $self->consumer;
#
# Start
#
$consumer->dsstart(@_);
#
# Loop
#
while (@_) {
#
# First our private thingies
#
while (@_ && ref $_[$ARRAY_START_INDICE]) {
if ($openaddr == refaddr $_[$ARRAY_START_INDICE]) { $consumer->dsopen ((splice @_, $ARRAY_START_INDICE, 2)[-1]) }
elsif ($closeaddr == refaddr $_[$ARRAY_START_INDICE]) { $consumer->dsclose((splice @_, $ARRAY_START_INDICE, 2)[-1]) }
else { last }
}
#
# Consumer's dsread() returns eventual inner content
#
unshift(@_,
$openaddr, $previous,
@{$inner},
$closeaddr, $previous
) if (@_ && defined($inner = $consumer->dsread($previous = shift)) && (reftype($inner) // '') eq 'ARRAY')
}
#
# End - return value of consumer's dsend() is what we return
#
return $consumer->dsend()
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Data::Scan - Stackfree arbitrary data scanner
=head1 VERSION
version 0.009
=head1 SYNOPSIS
use strict;
use warnings FATAL => 'all';
use Data::Scan;
use Data::Scan::Impl::Printer; # A Data::Printer implementation example
( run in 2.448 seconds using v1.01-cache-2.11-cpan-5735350b133 )