# $Id: Tools.pm 6839 2000-05-05 21:32:07Z rousskov $

# This program is copyrighted free software; you can redistribute it and/or 
# modify it under the same terms as Web Polygraph itself.

package BB::Tools;
use strict;

#
# carious BB tools
#

@BB::Tools::ISA = qw( Exporter );
@BB::Tools::EXPORT = qw ( &Breed &EvalVars &CloneArr &IpRange2arr );

sub Breed {
	my $source = shift;
	die unless $source;
	die(caller) unless scalar @_;

	my @kids = ();

	foreach my $cfg (@_) {
		my %c = %{$cfg};
		$c{'cmd_id'} = 2 + scalar @kids;
		my $clone = $source->clone(\%c) or die();
		push @kids, $clone;
	}

	return ( @kids );
}

sub EvalVars {
	my ($template, $cfg) = @_;
	die() unless $cfg;

	my ($n, $v);
	while ( ($n, $v) = each %{$cfg} ) {
		$template =~ s/\$$n\b/$v/mge;
		$template =~ s/\$\{$n\}/$v/mge;
	}

	return $template;
}

sub CloneArr {
	my ($arr, $cfg) = @_;

	my @clones = ();

	foreach (@{$arr}) {
		push @clones, $_->clone($cfg);
	}

	return [ @clones ];
}


sub IpRange2arr {
	my $range = shift;
	my @specs = split(/\./, $range);

	return () unless @specs > 1;

	my @bins = ();
	foreach my $spec (@specs) {
		my ($min, $max) = $spec =~ /-/ ?
			($spec =~ /^(\d+)-(\d+)$/) : ($spec =~ /^(\d+)$/);
		return undef unless defined $min;
		$max = $min if !defined($max);
		push @bins, { min=>$min, max=>$max, pos=>$min };
	}

	my @res = ();
	while (1) {
		push @res, &curAddr(\@bins);
	} continue {
		last unless nextIter(\@bins);
	}

	return @res;
}

sub nextIter {
	my ($bins, $level) = @_;
	$level = $#{$bins} if !defined $level;
	return undef if $level < 0;
	
	my $b = $bins->[$level];
	if ($b->{pos} >= $b->{max}) {
		$b->{pos} = $b->{min};
		return &nextIter($bins, $level-1);
	}
	$b->{pos}++;

	if ($b->{pos} % 255 == 0) { # skip 255s
		$b->{pos}++;
	}

	return 1;
}

sub curAddr {
	my $bins = shift;
	
	my $addr = '';
	for (my $i = 0; $i <= $#{$bins}; ++$i) {
		my $b = $bins->[$i];
		if ($b->{max} > 255) { # spill
			$addr .= sprintf("%d.", $b->{pos} / 255);
		}
		$addr .= sprintf("%d.", $b->{pos} % 255);
	}
	chop($addr);
	return $addr;
}

1;


syntax highlighted by Code2HTML, v. 0.9.1