📄 common.pm
字号:
]; push @EXPORT, @{ $EXPORT_TAGS{Parse} } ;use constant Parse_any => 0x01;use constant Parse_unsigned => 0x02;use constant Parse_signed => 0x04;use constant Parse_boolean => 0x08;use constant Parse_string => 0x10;use constant Parse_custom => 0x12;#use constant Parse_store_ref => 0x100 ;use constant Parse_multiple => 0x100 ;use constant Parse_writable => 0x200 ;use constant Parse_writable_scalar => 0x400 | Parse_writable ;use constant OFF_PARSED => 0 ;use constant OFF_TYPE => 1 ;use constant OFF_DEFAULT => 2 ;use constant OFF_FIXED => 3 ;use constant OFF_FIRST_ONLY => 4 ;use constant OFF_STICKY => 5 ;sub ParseParameters{ my $level = shift || 0 ; my $sub = (caller($level + 1))[3] ; local $Carp::CarpLevel = 1 ; my $p = new IO::Compress::Base::Parameters() ; $p->parse(@_) or croak "$sub: $p->{Error}" ; return $p;}#package IO::Compress::Base::Parameters;use strict;use warnings;use Carp;sub IO::Compress::Base::Parameters::new{ my $class = shift ; my $obj = { Error => '', Got => {}, } ; #return bless $obj, ref($class) || $class || __PACKAGE__ ; return bless $obj, 'IO::Compress::Base::Parameters' ;}sub IO::Compress::Base::Parameters::setError{ my $self = shift ; my $error = shift ; my $retval = @_ ? shift : undef ; $self->{Error} = $error ; return $retval;} #sub getError#{# my $self = shift ;# return $self->{Error} ;#} sub IO::Compress::Base::Parameters::parse{ my $self = shift ; my $default = shift ; my $got = $self->{Got} ; my $firstTime = keys %{ $got } == 0 ; my (@Bad) ; my @entered = () ; # Allow the options to be passed as a hash reference or # as the complete hash. if (@_ == 0) { @entered = () ; } elsif (@_ == 1) { my $href = $_[0] ; return $self->setError("Expected even number of parameters, got 1") if ! defined $href or ! ref $href or ref $href ne "HASH" ; foreach my $key (keys %$href) { push @entered, $key ; push @entered, \$href->{$key} ; } } else { my $count = @_; return $self->setError("Expected even number of parameters, got $count") if $count % 2 != 0 ; for my $i (0.. $count / 2 - 1) { push @entered, $_[2* $i] ; push @entered, \$_[2* $i+1] ; } } while (my ($key, $v) = each %$default) { croak "need 4 params [@$v]" if @$v != 4 ; my ($first_only, $sticky, $type, $value) = @$v ; my $x ; $self->_checkType($key, \$value, $type, 0, \$x) or return undef ; $key = lc $key; if ($firstTime || ! $sticky) { $x = [ $x ] if $type & Parse_multiple; $got->{$key} = [0, $type, $value, $x, $first_only, $sticky] ; } $got->{$key}[OFF_PARSED] = 0 ; } my %parsed = (); for my $i (0.. @entered / 2 - 1) { my $key = $entered[2* $i] ; my $value = $entered[2* $i+1] ; #print "Key [$key] Value [$value]" ; #print defined $$value ? "[$$value]\n" : "[undef]\n"; $key =~ s/^-// ; my $canonkey = lc $key; if ($got->{$canonkey} && ($firstTime || ! $got->{$canonkey}[OFF_FIRST_ONLY] )) { my $type = $got->{$canonkey}[OFF_TYPE] ; my $parsed = $parsed{$canonkey}; ++ $parsed{$canonkey}; return $self->setError("Muliple instances of '$key' found") if $parsed && $type & Parse_multiple == 0 ; my $s ; $self->_checkType($key, $value, $type, 1, \$s) or return undef ; $value = $$value ; if ($type & Parse_multiple) { $got->{$canonkey}[OFF_PARSED] = 1; push @{ $got->{$canonkey}[OFF_FIXED] }, $s ; } else { $got->{$canonkey} = [1, $type, $value, $s] ; } } else { push (@Bad, $key) } } if (@Bad) { my ($bad) = join(", ", @Bad) ; return $self->setError("unknown key value(s) @Bad") ; } return 1;}sub IO::Compress::Base::Parameters::_checkType{ my $self = shift ; my $key = shift ; my $value = shift ; my $type = shift ; my $validate = shift ; my $output = shift; #local $Carp::CarpLevel = $level ; #print "PARSE $type $key $value $validate $sub\n" ; if ($type & Parse_writable_scalar) { return $self->setError("Parameter '$key' not writable") if $validate && readonly $$value ; if (ref $$value) { return $self->setError("Parameter '$key' not a scalar reference") if $validate && ref $$value ne 'SCALAR' ; $$output = $$value ; } else { return $self->setError("Parameter '$key' not a scalar") if $validate && ref $value ne 'SCALAR' ; $$output = $value ; } return 1; }# if ($type & Parse_store_ref)# {# #$value = $$value# # if ref ${ $value } ;## $$output = $value ;# return 1;# } $value = $$value ; if ($type & Parse_any) { $$output = $value ; return 1; } elsif ($type & Parse_unsigned) { return $self->setError("Parameter '$key' must be an unsigned int, got 'undef'") if $validate && ! defined $value ; return $self->setError("Parameter '$key' must be an unsigned int, got '$value'") if $validate && $value !~ /^\d+$/; $$output = defined $value ? $value : 0 ; return 1; } elsif ($type & Parse_signed) { return $self->setError("Parameter '$key' must be a signed int, got 'undef'") if $validate && ! defined $value ; return $self->setError("Parameter '$key' must be a signed int, got '$value'") if $validate && $value !~ /^-?\d+$/; $$output = defined $value ? $value : 0 ; return 1 ; } elsif ($type & Parse_boolean) { return $self->setError("Parameter '$key' must be an int, got '$value'") if $validate && defined $value && $value !~ /^\d*$/; $$output = defined $value ? $value != 0 : 0 ; return 1; } elsif ($type & Parse_string) { $$output = defined $value ? $value : "" ; return 1; } $$output = $value ; return 1;}sub IO::Compress::Base::Parameters::parsed{ my $self = shift ; my $name = shift ; return $self->{Got}{lc $name}[OFF_PARSED] ;}sub IO::Compress::Base::Parameters::value{ my $self = shift ; my $name = shift ; if (@_) { $self->{Got}{lc $name}[OFF_PARSED] = 1; $self->{Got}{lc $name}[OFF_DEFAULT] = $_[0] ; $self->{Got}{lc $name}[OFF_FIXED] = $_[0] ; } return $self->{Got}{lc $name}[OFF_FIXED] ;}sub IO::Compress::Base::Parameters::valueOrDefault{ my $self = shift ; my $name = shift ; my $default = shift ; my $value = $self->{Got}{lc $name}[OFF_DEFAULT] ; return $value if defined $value ; return $default ;}sub IO::Compress::Base::Parameters::wantValue{ my $self = shift ; my $name = shift ; return defined $self->{Got}{lc $name}[OFF_DEFAULT] ;}sub IO::Compress::Base::Parameters::clone{ my $self = shift ; my $obj = { }; my %got ; while (my ($k, $v) = each %{ $self->{Got} }) { $got{$k} = [ @$v ]; } $obj->{Error} = $self->{Error}; $obj->{Got} = \%got ; return bless $obj, 'IO::Compress::Base::Parameters' ;}package U64;use constant MAX32 => 0xFFFFFFFF ;use constant LOW => 0 ;use constant HIGH => 1;sub new{ my $class = shift ; my $high = 0 ; my $low = 0 ; if (@_ == 2) { $high = shift ; $low = shift ; } elsif (@_ == 1) { $low = shift ; } bless [$low, $high], $class;}sub newUnpack_V64{ my $string = shift; my ($low, $hi) = unpack "V V", $string ; bless [ $low, $hi ], "U64";}sub newUnpack_V32{ my $string = shift; my $low = unpack "V", $string ; bless [ $low, 0 ], "U64";}sub reset{ my $self = shift; $self->[HIGH] = $self->[LOW] = 0;}sub clone{ my $self = shift; bless [ @$self ], ref $self ;}sub getHigh{ my $self = shift; return $self->[HIGH];}sub getLow{ my $self = shift; return $self->[LOW];}sub get32bit{ my $self = shift; return $self->[LOW];}sub add{ my $self = shift; my $value = shift; if (ref $value eq 'U64') { $self->[HIGH] += $value->[HIGH] ; $value = $value->[LOW]; } my $available = MAX32 - $self->[LOW] ; if ($value > $available) { ++ $self->[HIGH] ; $self->[LOW] = $value - $available - 1; } else { $self->[LOW] += $value ; }}sub equal{ my $self = shift; my $other = shift; return $self->[LOW] == $other->[LOW] && $self->[HIGH] == $other->[HIGH] ;}sub getPacked_V64{ my $self = shift; return pack "V V", @$self ;}sub getPacked_V32{ my $self = shift; return pack "V", $self->[LOW] ;}sub pack_V64{ my $low = shift; return pack "V V", $low, 0;}package IO::Compress::Base::Common;1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -