diff --git a/Changes b/Changes index e7a2f3f..234d1ba 100644 --- a/Changes +++ b/Changes @@ -1,13 +1,23 @@ Revision history for Perl extension NetAddr::IP -4.050 Sat Oct 22 01:58:57 PDT 2011 +4.051 Mon Oct 24 14:44:53 PDT 2011 + fix bug 71869 + in Lite.pm v1.34 + use Math::BigInt::Calc for creating BigInt values and fall + back to NetAddr::IP::Calc if Math::BigInt is not present. + + remove reference to Config{osname} in InetBase.pm v0.03 + (Util 1.43) + + +4.050 Sat Oct 22 01:58:57 PDT 2011 In Lite/Util/lib/NetAddr/IP/Lite/Util/InetBase.pm v0.02 Socket6 prior to version 0.23 does not have AF_INET6 in the EXPORT_OK array, modify InetBase.pm v0.2 to work around this. Add support for Math::BigInt to NetAddr::IP::Lite v1.33 -4.049 Sat Oct 15 22:15:10 PDT 2011 +4.049 Sat Oct 15 22:15:10 PDT 2011 Updates to Lite.pm, Util.pm, new module InetBase.pm In Lite v1.32 @@ -43,7 +53,7 @@ AF_INET AF_INET6 -4.048 Sat Oct 8 01:33:44 PDT 2011 +4.048 Sat Oct 8 01:33:44 PDT 2011 remove debug print statement from Util v1.40 4.047 Thu Oct 6 23:41:42 PDT 2011 diff --git a/IP.pm b/IP.pm index 8b64154..702b1ad 100644 --- a/IP.pm +++ b/IP.pm @@ -35,7 +35,7 @@ @ISA = qw(Exporter NetAddr::IP::Lite); -$VERSION = do { sprintf " %d.%03d", (q$Revision: 4.50 $ =~ /\d+/g) }; +$VERSION = do { sprintf " %d.%03d", (q$Revision: 4.51 $ =~ /\d+/g) }; =pod @@ -189,7 +189,7 @@ This module provides an object-oriented abstraction on top of IP addresses or IP subnets, that allows for easy manipulations. Version 4.xx of NetAdder::IP will will work with older -versions of Perl and does B use but is compatible with Math::BigInt. +versions of Perl and is compatible with Math::BigInt. The internal representation of all IP objects is in 128 bit IPv6 notation. IPv4 and IPv6 objects may be freely mixed. diff --git a/Lite/Calc.pm b/Lite/Calc.pm new file mode 100644 index 0000000..43aad3d --- /dev/null +++ b/Lite/Calc.pm @@ -0,0 +1,162 @@ +package NetAddr::IP::Calc; + +use diagnostics; +use strict; +use vars qw($VERSION); + +$VERSION = '1.997'; + +# Package to store unsigned big integers in decimal and do math with them + +# Internally the numbers are stored in an array with at least 1 element, no +# leading zero parts (except the first) and in base 1eX where X is determined +# automatically at loading time to be the maximum possible value + +# todo: +# - fully remove funky $# stuff in div() (maybe - that code scares me...) + +# USE_MUL: due to problems on certain os (os390, posix-bc) "* 1e-5" is used +# instead of "/ 1e5" at some places, (marked with USE_MUL). Other platforms +# BS2000, some Crays need USE_DIV instead. +# The BEGIN block is used to determine which of the two variants gives the +# correct result. + +# Beware of things like: +# $i = $i * $y + $car; $car = int($i / $BASE); $i = $i % $BASE; +# This works on x86, but fails on ARM (SA1100, iPAQ) due to whoknows what +# reasons. So, use this instead (slower, but correct): +# $i = $i * $y + $car; $car = int($i / $BASE); $i -= $BASE * $car; + +############################################################################## +# global constants, flags and accessory + +# announce that we are compatible with MBI v1.83 and up +sub api_version () { 2; } + +# constants for easier life +my ($BASE,$BASE_LEN,$RBASE); + +sub _base_len + { + # Set/get the BASE_LEN and assorted other, connected values. + # Used only by the testsuite, the set variant is used only by the BEGIN + # block below: + shift; + + my ($b, $int) = @_; + if (defined $b) + { + if ($] >= 5.008 && $int && $b > 7) + { + $BASE_LEN = $b; + $BASE = int("1e".$BASE_LEN); + return $BASE_LEN; + } + + # find whether we can use mul or div in mul()/div() + $BASE_LEN = $b+1; + my $caught = 0; + while (--$BASE_LEN > 5) + { + $BASE = int("1e".$BASE_LEN); + $RBASE = abs('1e-'.$BASE_LEN); # see USE_MUL + $caught = 0; + $caught += 1 if (int($BASE * $RBASE) != 1); # should be 1 + $caught += 2 if (int($BASE / $BASE) != 1); # should be 1 + last if $caught != 3; + } + } + return $BASE_LEN; + } + +sub _new + { + # (ref to string) return ref to num_array + # Convert a number from string format (without sign) to internal base + # 1ex format. Assumes normalized value as input. + my $il = length($_[1])-1; + + # < BASE_LEN due len-1 above + return [ int($_[1]) ] if $il < $BASE_LEN; # shortcut for short numbers + + # this leaves '00000' instead of int 0 and will be corrected after any op + [ reverse(unpack("a" . ($il % $BASE_LEN+1) + . ("a$BASE_LEN" x ($il / $BASE_LEN)), $_[1])) ]; + } + +BEGIN + { + # from Daniel Pfeiffer: determine largest group of digits that is precisely + # multipliable with itself plus carry + # Test now changed to expect the proper pattern, not a result off by 1 or 2 + my ($e, $num) = 3; # lowest value we will use is 3+1-1 = 3 + do + { + $num = ('9' x ++$e) + 0; + $num *= $num + 1.0; + } while ("$num" =~ /9{$e}0{$e}/); # must be a certain pattern + $e--; # last test failed, so retract one step + # the limits below brush the problems with the test above under the rug: + # the test should be able to find the proper $e automatically + $e = 5 if $^O =~ /^uts/; # UTS get's some special treatment + $e = 5 if $^O =~ /^unicos/; # unicos is also problematic (6 seems to work + # there, but we play safe) + + my $int = 0; + if ($e > 7) + { + use integer; + my $e1 = 7; + $num = 7; + do + { + $num = ('9' x ++$e1) + 0; + $num *= $num + 1; + } while ("$num" =~ /9{$e1}0{$e1}/); # must be a certain pattern + $e1--; # last test failed, so retract one step + if ($e1 > 7) + { + $int = 1; $e = $e1; + } + } + + __PACKAGE__->_base_len($e,$int); # set and store + } + +=head1 LICENSE + +This program is free software; you may redistribute it and/or modify it under +the same terms as Perl itself. + +=head1 AUTHORS + +=over 4 + +=item * + +Original math code by Mark Biggar, rewritten by Tels L +in late 2000. + +=item * + +Separated from BigInt and shaped API with the help of John Peacock. + +=item * + +Fixed, speed-up, streamlined and enhanced by Tels 2001 - 2007. + +=item * + +API documentation corrected and extended by Peter John Acklam, +Epjacklam@online.noE + +=item * + +Shortened to base length check only for use with NetAddr::IP by +Michael Robinton emichael@bizsystems.comE + +=back + +=cut + +1; diff --git a/Lite/Changes b/Lite/Changes index c2b80fb..76b01e3 100644 --- a/Lite/Changes +++ b/Lite/Changes @@ -1,5 +1,12 @@ Revision history for Perl extension NetAddr::IP::Lite +1.34 Mon Oct 24 14:38:16 PDT 2011 + use Math::BigInt::Calc for creating BigInt values and fall + back to NetAddr::IP::Calc if Math::BigInt is not present. + + remove reference to Config{osname} in InetBase.pm v0.03 + (Util 1.43) + 1.33 Sat Oct 22 01:47:42 PDT 2011 In Lite/Util/lib/NetAddr/IP/Lite/Util/InetBase.pm v0.02 Socket6 prior to version 0.23 does not have AF_INET6 in the diff --git a/Lite/Lite.pm b/Lite/Lite.pm index b0b13de..f0f31e6 100644 --- a/Lite/Lite.pm +++ b/Lite/Lite.pm @@ -32,7 +32,7 @@ use vars qw(@ISA @EXPORT_OK $VERSION $Accept_Binary_IP $Old_nth $AUTOLOAD *Zero); -$VERSION = do { my @r = (q$Revision: 1.33 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; +$VERSION = do { my @r = (q$Revision: 1.34 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; require Exporter; @@ -113,7 +113,7 @@ This module provides an object-oriented abstraction on top of IP addresses or IP subnets, that allows for easy manipulations. Most of the operations of NetAddr::IP are supported. This module will work with older -versions of Perl and does B use but is compatible with Math::BigInt. +versions of Perl and is compatible with Math::BigInt. * By default B functions and methods return string IPv6 addresses in uppercase. To change that to lowercase: @@ -1180,24 +1180,20 @@ =cut +my $biloaded; + sub _biValue { - my $bi; - unless ($_[0]) { - $bi = { - sign => '+', - value => ['0'], - }; - return bless $bi, 'Math::BigInt'; + unless ($biloaded) { + if (eval {require Math::BigInt::Calc}) { + $biloaded = \&Math::BigInt::Calc::_new; + } else { + require NetAddr::IP::Calc; + $biloaded = \&NetAddr::IP::Calc::_new; + } } - my $numstr = $_[0]; - my @bi; - while ($numstr) { - my $nibble = substr($numstr,-7,7,''); - push @bi, $nibble; - } - $bi = { + my $bi = { sign => '+', - value => \@bi, + value => $biloaded->(undef,$_[0]), }; bless $bi, 'Math::BigInt'; } diff --git a/Lite/MANIFEST b/Lite/MANIFEST index 600fe4c..57a22da 100644 --- a/Lite/MANIFEST +++ b/Lite/MANIFEST @@ -1,6 +1,7 @@ MANIFEST MANIFEST.SKIP Changes +Calc.pm Lite.pm Makefile.PL META.yml diff --git a/Lite/README b/Lite/README index 6bc3364..bbd0e57 100644 --- a/Lite/README +++ b/Lite/README @@ -58,8 +58,8 @@ DESCRIPTION This module provides an object-oriented abstraction on top of IP addresses or IP subnets, that allows for easy manipulations. Most of the - operations of NetAddr::IP are supported. This module will work older - versions of Perl and does not use but is compatible with Math::BigInt. + operations of NetAddr::IP are supported. This module will work with + older versions of Perl and is compatible with Math::BigInt. * By default NetAddr::IP functions and methods return string IPv6 addresses in uppercase. To change that to lowercase: @@ -343,7 +343,7 @@ "->numeric()" When called in a scalar context, will return a numeric representation of the address part of the IP address. When called in - an array contest, it returns a list of two elements. The first + an array context, it returns a list of two elements. The first element is as described, the second element is the numeric representation of the netmask. diff --git a/Lite/Util/Changes b/Lite/Util/Changes index c0385cd..1f41c76 100644 --- a/Lite/Util/Changes +++ b/Lite/Util/Changes @@ -1,3 +1,6 @@ +1.43 Mon Oct 24 13:25:09 PDT 2011 + remove reference to Config{osname} in InetBase.pm v0.03 + 1.42 Fri Oct 21 10:34:46 PDT 2011 Socket6 prior to version 0.23 does not have AF_INET6 in the EXPORT_OK array, modify InetBase.pm v0.2 to work around this. diff --git a/Lite/Util/Util.pm b/Lite/Util/Util.pm index 058693a..6f98b48 100644 --- a/Lite/Util/Util.pm +++ b/Lite/Util/Util.pm @@ -21,7 +21,7 @@ @ISA = qw(Exporter DynaLoader); -$VERSION = do { my @r = (q$Revision: 1.42 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; +$VERSION = do { my @r = (q$Revision: 1.43 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; @EXPORT_OK = qw( inet_aton diff --git a/Lite/Util/lib/NetAddr/IP/InetBase.pm b/Lite/Util/lib/NetAddr/IP/InetBase.pm index 5fd67ec..b7a4b56 100644 --- a/Lite/Util/lib/NetAddr/IP/InetBase.pm +++ b/Lite/Util/lib/NetAddr/IP/InetBase.pm @@ -11,7 +11,7 @@ @ISA = qw(Exporter); -$VERSION = do { my @r = (q$Revision: 0.02 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; +$VERSION = do { my @r = (q$Revision: 0.03 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; @EXPORT_OK = qw( inet_aton @@ -91,17 +91,15 @@ $emulateAF_INET6 = 0; # clear, have it from elsewhere or here } else { unless ($emulateAF_INET6) { # unlikely at this point - require Config; # make an educated guess about AF_INET6 - my $osname = $Config::Config{osname}; - if ($osname =~ /(?:free|dragon.+)bsd/i) { # FreeBSD, DragonFlyBSD + if ($^O =~ /(?:free|dragon.+)bsd/i) { # FreeBSD, DragonFlyBSD $emulateAF_INET6 = 28; - } elsif ($osname =~ /bsd/i) { # other BSD flavors like NetBDS, OpenBSD, BSD + } elsif ($^O =~ /bsd/i) { # other BSD flavors like NetBDS, OpenBSD, BSD $emulateAF_INET6 = 24; - } elsif ($osname =~ /(?:darwin|mac)/i) { # Mac OS X + } elsif ($^O =~ /(?:darwin|mac)/i) { # Mac OS X $emulateAF_INET6 = 30; - } elsif ($osname =~ /win/i) { # Windows + } elsif ($^O =~ /win/i) { # Windows $emulateAF_INET6 = 23; - } elsif ($osname =~ /(?:solaris|sun)/i) { # Sun box + } elsif ($^O =~ /(?:solaris|sun)/i) { # Sun box $emulateAF_INET6 = 26; } else { # use linux default $emulateAF_INET6 = 10; diff --git a/MANIFEST b/MANIFEST index 7bf4439..53634d5 100644 --- a/MANIFEST +++ b/MANIFEST @@ -38,6 +38,7 @@ t/v6-splitplan.t t/wildcard.t Lite/Changes +Lite/Calc.pm Lite/Lite.pm Lite/MANIFEST Lite/MANIFEST.SKIP diff --git a/META.yml b/META.yml index fc1965d..fd06cc8 100644 --- a/META.yml +++ b/META.yml @@ -1,6 +1,6 @@ --- #YAML:1.0 name: NetAddr-IP -version: 4.050 +version: 4.051 abstract: Manages IPv4 and IPv6 addresses and subnets license: ~ author: