File Coverage

blib/lib/Blockchain/Ethereum/ABI/Type/Int.pm
Criterion Covered Total %
statement 48 49 97.9
branch 18 20 90.0
condition 11 12 91.6
subroutine 12 12 100.0
pod 3 3 100.0
total 92 96 95.8


line stmt bran cond sub pod time code
1             package Blockchain::Ethereum::ABI::Type::Int;
2              
3 8     8   221474 use v5.26;
  8         45  
4 8     8   80 use strict;
  8         86  
  8         278  
5 8     8   42 use warnings;
  8         23  
  8         926  
6              
7             # ABSTRACT: Solidity uint/int/bool type interface
8             our $AUTHORITY = 'cpan:REFECO'; # AUTHORITY
9             our $VERSION = '0.021'; # VERSION
10              
11 8     8   78 use parent 'Blockchain::Ethereum::ABI::Type';
  8         16  
  8         678  
12              
13 8     8   734 use Carp;
  8         29  
  8         825  
14 8     8   12994 use Math::BigInt try => 'GMP';
  8         451857  
  8         64  
15 8     8   275045 use Scalar::Util qw(looks_like_number);
  8         31  
  8         792  
16              
17             use constant {
18 8         6188 DEFAULT_INT_SIZE => 256,
19             HFF => '0x' . 'F' x 64,
20             HMAX => '0x8' . '0' x 63
21 8     8   59 };
  8         14  
22              
23 66     66   144 sub _configure { return }
24              
25             sub encode {
26 89     89 1 139 my $self = shift;
27              
28 89 100       228 return $self->_encoded if $self->_encoded;
29              
30 40 100       206 croak "Invalid numeric data @{[$self->{data}]}" unless looks_like_number($self->{data});
  1         224  
31              
32 39         224 my $bdata = Math::BigInt->new($self->{data});
33              
34 39 50       4315 croak "Invalid numeric data @{[$self->{data}]}" if $bdata->is_nan;
  0         0  
35              
36 39 100 66     371 croak "Invalid data length, signature: @{[$self->fixed_length]}, data length: @{[$bdata->length]}"
  1         5  
  1         4  
37             if $self->fixed_length && $bdata->length > $self->fixed_length;
38              
39 2         418 croak "Invalid negative numeric data @{[$self->{data}]}"
40 38 100 100     140 if $bdata->is_neg && $self->{signature} =~ /^uint|bool/;
41              
42 1         232 croak "Invalid bool data it must be 1 or 0 but given @{[$self->{data}]}"
43 36 100 100     323 if !$bdata->is_zero && !$bdata->is_one && $self->{signature} =~ /^bool/;
      100        
44              
45 35 100       1058 $bdata->bneg->bxor(HFF)->binc if $bdata->is_neg;
46              
47 35         2712 $self->_push_static($self->pad_left($bdata->to_hex));
48              
49 35         107 return $self->_encoded;
50             }
51              
52             sub decode {
53 15     15 1 19 my $self = shift;
54              
55 15 50       84 my $bdata = Math::BigInt->from_hex(ref $self->{data} eq 'ARRAY' ? $self->{data}->[0] : $self->{data});
56              
57 15 100       7106 $bdata->bxor(HFF)->binc->bneg if $bdata->copy->band(HMAX);
58              
59 15         24675 return $bdata;
60             }
61              
62             sub fixed_length {
63 79     79 1 939 my $self = shift;
64              
65 79 100       363 if ($self->{signature} =~ /[a-z](\d+)/) {
66 61         359 return $1;
67             }
68 18         117 return DEFAULT_INT_SIZE;
69             }
70              
71             1;
72              
73             __END__