Net-DNS

 view release on metacpan or  search on metacpan

lib/Net/DNS/ZoneFile.pm  view on Meta::CPAN

	}

	sub input_line_number {
		return shift->{line};
	}

}


=head2 readfh

	$listref = Net::DNS::ZoneFile->readfh( $filehandle );
	$listref = Net::DNS::ZoneFile->readfh( $filehandle, $include_dir );

readfh() parses data from the specified file handle
and returns a reference to the list of Net::DNS::RR objects.
The return value is undefined if an error is encountered by the parser.

=cut

sub readfh {
	return &_read;
}


=head2 parse

	$listref = Net::DNS::ZoneFile->parse( $string );
	$listref = Net::DNS::ZoneFile->parse( $string, $include_dir );
	$listref = Net::DNS::ZoneFile->parse( \$string );
	$listref = Net::DNS::ZoneFile->parse( \$string, $include_dir );

parse() interprets the text in the argument string
and returns a reference to the list of Net::DNS::RR objects.
The return value is undefined if an error is encountered by the parser.

=cut

sub parse {
	my ($arg1) = @_;
	shift if $arg1 eq __PACKAGE__;
	my $string  = shift;
	my @include = grep {defined} shift;
	return &readfh( Net::DNS::ZoneFile::Text->new($string), @include );
}


########################################


{

	package Net::DNS::ZoneFile::Generator;	## no critic ProhibitMultiplePackages

	use overload ( '<>' => 'readline' );

	sub new {
		my ( $class, $range, $template, $line ) = @_;
		my $self = bless {}, $class;

		my ( $bound, $step ) = split m#[/]#, $range;	# initial iterator state
		my ( $first, $last ) = split m#[-]#, $bound;
		$first ||= 0;
		$last  ||= $first;
		$step  ||= 1;					# coerce step to match range
		$step = ( $last < $first ) ? -abs($step) : abs($step);
		$self->{count} = int( ( $last - $first ) / $step ) + 1;

		for ($template) {
			s/\\\$/\\036/g;				# disguise escaped dollar
			s/\$\$/\\036/g;				# disguise escaped dollar
			s/^"(.*)"$/$1/s;			# unwrap BIND's quoted template
			@{$self}{qw(instant step template line)} = ( $first, $step, $_, $line );
		}
		return $self;
	}

	sub readline {
		my $self = shift;
		return unless $self->{count}-- > 0;		# EOF

		my $instant = $self->{instant};			# update iterator state
		$self->{instant} += $self->{step};

		local $_ = $self->{template};			# copy template
		while (/\$\{(.*)\}/) {				# interpolate ${...}
			my $s = _format( $instant, split /\,/, $1 );
			s/\$\{$1\}/$s/eg;
		}

		s/\$/$instant/eg;				# interpolate $
		s/\\036/\$/g;					# reinstate escaped $
		return $_;
	}

	sub close {
		shift->{count} = 0;				# suppress iterator
		return 1;
	}

	sub input_line_number {
		return shift->{line};				# fixed: identifies $GENERATE
	}


	sub _format {			## convert $GENERATE iteration number to specified format
		my $number = shift;				# per ISC BIND 9.7
		my $offset = shift || 0;
		my $length = shift || 0;
		my $format = shift || 'd';

		my $value = $number + $offset;
		my $digit = $length || 1;
		return substr sprintf( "%01.$digit$format", $value ), -$length if $format =~ /[doxX]/;

		my $nibble = join( '.', split //, sprintf ".%32.32lx", $value );
		return reverse lc( substr $nibble, -$length ) if $format =~ /[n]/;
		return reverse uc( substr $nibble, -$length ) if $format =~ /[N]/;
		die "unknown $format format";
	}

}



( run in 0.791 second using v1.01-cache-2.11-cpan-71847e10f99 )