File Coverage

blib/lib/Blockchain/Ethereum/ABI/Type/Array.pm
Criterion Covered Total %
statement 47 49 95.9
branch 12 14 85.7
condition 6 8 75.0
subroutine 11 11 100.0
pod 3 3 100.0
total 79 85 92.9


line stmt bran cond sub pod time code
1             package Blockchain::Ethereum::ABI::Type::Array;
2              
3 5     5   2740 use v5.26;
  5         24  
4 5     5   27 use strict;
  5         10  
  5         108  
5 5     5   25 use warnings;
  5         10  
  5         128  
6              
7 5     5   24 use Carp;
  5         29  
  5         344  
8 5     5   36 use parent qw(Blockchain::Ethereum::ABI::Type);
  5         9  
  5         26  
9              
10             sub _configure {
11 20     20   36 my $self = shift;
12 20 100       67 return unless $self->_data;
13              
14 17         42 for my $item ($self->_data->@*) {
15 36         96 push $self->_instances->@*,
16             Blockchain::Ethereum::ABI::Type::new_type(
17             signature => $self->_remove_parent,
18             data => $item
19             );
20             }
21             }
22              
23             sub encode {
24 39     39 1 63 my $self = shift;
25 39 100       93 return $self->_encoded if $self->_encoded;
26              
27 17         58 my $length = scalar $self->_data->@*;
28             # for dynamic length arrays the length must be included
29 17 100       47 $self->_push_static($self->_encode_length($length))
30             unless $self->fixed_length;
31              
32 17 100 100     71 croak "Invalid array size, signature @{[$self->fixed_length]}, data: $length"
  1         3  
33             if $self->fixed_length && $length > $self->fixed_length;
34              
35 16         64 my $offset = $self->_get_initial_offset;
36              
37 16         60 for my $instance ($self->_instances->@*) {
38 32 100       68 $self->_push_static($self->_encode_offset($offset))
39             if $instance->is_dynamic;
40              
41 32         80 $self->_push_dynamic($instance->encode);
42 32         81 $offset += scalar $instance->encode()->@*;
43             }
44              
45 16         49 return $self->_encoded;
46             }
47              
48             sub decode {
49 3     3 1 6 my $self = shift;
50 3         8 my @data = $self->_data->@*;
51              
52 3   66     6 my $size = $self->fixed_length // shift $self->_data->@*;
53 3         16 push $self->_instances->@*, Blockchain::Ethereum::ABI::Type::new_type(signature => $self->_remove_parent) for 0 .. $size - 1;
54              
55 3         33 return $self->_read_stack_set_data;
56             }
57              
58             sub _remove_parent {
59 43     43   78 my $self = shift;
60 43         122 $self->_signature =~ /(\[(\d+)?\]$)/;
61 43   50     113 return substr $self->_signature, 0, length($self->_signature) - length($1 // '');
62             }
63              
64             sub fixed_length {
65 44     44 1 74 my $self = shift;
66 44 50       91 if ($self->_signature =~ /\[(\d+)?\]$/) {
67 44         445 return $1;
68             }
69 0         0 return undef;
70             }
71              
72             sub _static_size {
73 2     2   4 my $self = shift;
74 2 50       5 return 1 if $self->is_dynamic;
75              
76 2         5 my $size = $self->fixed_length;
77              
78 2         4 my $instance_size = 1;
79 2         9 for my $instance ($self->_instances->@*) {
80 0         0 $instance_size += $instance->_static_size;
81             }
82              
83 2         6 return $size * $instance_size;
84             }
85              
86             1;
87              
88             __END__