Array-IntSpan

 view release on metacpan or  search on metacpan

lib/Array/IntSpan/Fields.pm  view on Meta::CPAN

        push @result, $res ;
      }

    return wantarray ? @result : $result[0];
  }

sub get_range 
  {
    my ($self,$s_field,$e_field) = splice @_,0,3 ;
    my ($s, $e) = $self->field_to_int($s_field,$e_field) ;
    my @newcb = $self->adapt_range_in_cb(@_) ;

    my $got = $self->{range}->get_range($s,$e,@newcb) ;

    my $ret = bless {range => $got }, ref($self) ;
    $ret->set_format($self->{format}) ;
    return $ret ;
  }

sub lookup
  {
    my $self = shift;
    my @keys = $self->field_to_int(@_);
    $self->{range}->lookup(@keys) ;
  }

sub clear
  {
    my $self = shift;
    @{$self->{range}} = () ;
  }

sub consolidate
  {
    my ($self,$s_field,$e_field) = splice @_,0,3 ;
    my ($s, $e) = $self->field_to_int($s_field,$e_field) 
      if defined $s_field and defined $e_field;
    my @newcb = $self->adapt_range_in_cb(@_) if @_;

    return $self->{range}->consolidate($s,$e,@newcb) ;
  }


foreach my $method (qw/set_range set_consolidate_range/)
  {
    no strict 'refs' ;
    *$method = sub 
      {
        my ($self,$s_field,$e_field,$value) = splice @_,0,4 ;
        my ($s, $e) = $self->field_to_int($s_field,$e_field) ;
        my @newcb = $self->adapt_range_in_cb(@_) ;

        return $self->{range}->$method ($s, $e, $value, @newcb);
      };
  }

sub adapt_range_in_cb
  {
    my $self = shift;

    # the callbacks will be called with ($start, $end,$payload) or
    # ($start,$end)
    my @callbacks = @_ ; 

    return map
      {
        my $old_cb = $_; # required for closure to work
        defined $old_cb ?
          sub
            {
              my ($s_int,$e_int,$value) = @_ ;
              my ($s,$e) = $self->int_to_field($s_int,$e_int) ;
              $old_cb->($s,$e,$value);
            }
              : undef ;
      } @callbacks ;
  }

sub get_element
  {
    my ($self,$idx) = @_;
    my $elt = $self->{range}[$idx] || return () ;
    my ($s_int,$e_int,$value) = @$elt ;
    my ($s,$e) = $self->int_to_field($s_int,$e_int) ;

    return ($s,$e, $value) ;
  }

1;

__END__

=head1 NAME

Array::IntSpan::Fields -  IntSpan array using integer fields as indices

=head1 SYNOPSIS

  use Array::IntSpan::Fields;

  my $foo = Array::IntSpan::Fields
   ->new( '1.2.4',
          ['0.0.1','0.1.0','ab'],
          ['1.0.0','1.0.3','cd']);

  print "Address 0.0.15 has ".$foo->lookup("0.0.15").".\n";

  $foo->set_range('1.0.4','1.1.0','ef') ;

=head1 DESCRIPTION

C<Array::IntSpan::Fields> brings the advantages of C<Array::IntSpan>
to indices made of integer fields like an IP address and an ANSI SS7 point code.

The number of integer and their maximum value is defined when calling
the constructor (or the C<set_format> method). The example in the
synopsis defines an indice with 3 fields where their maximum values
are 1,3,15 (or 0x1,0x3,0xf).

This module converts the fields into integer before storing them into
the L<Array::IntSpan> module.

=head1 CONSTRUCTOR

=head2 new (...)

The first parameter defines the size of the integer of the fields, in
number of bits. For an IP address, the field definition would be
C<8,8,8,8>.

=head1 METHODS

All methods of L<Array::IntSpan> are available.

=head2 set_format( field_description )



( run in 1.587 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )