File Coverage

blib/lib/Blockchain/Ethereum/ABI/Type/Array.pm
Criterion Covered Total %
statement 47 49 95.9
branch 12 14 85.7
condition 7 8 87.5
subroutine 11 11 100.0
pod 3 3 100.0
total 80 85 94.1


line stmt bran cond sub pod time code
1             package Blockchain::Ethereum::ABI::Type::Array;
2              
3 7     7   158314 use v5.26;
  7         27  
4 7     7   44 use strict;
  7         16  
  7         218  
5 7     7   31 use warnings;
  7         15  
  7         802  
6              
7             # ABSTRACT: Solidity array type interface
8             our $AUTHORITY = 'cpan:REFECO'; # AUTHORITY
9             our $VERSION = '0.021'; # VERSION
10              
11 7     7   70 use parent 'Blockchain::Ethereum::ABI::Type';
  7         14  
  7         80  
12              
13 7     7   488 use Carp;
  7         13  
  7         5369  
14              
15             sub _configure {
16 22     22   38 my $self = shift;
17              
18 22 100       104 return unless $self->{data};
19              
20 18         48 for my $item ($self->{data}->@*) {
21             push $self->{instances}->@*,
22 54         161 Blockchain::Ethereum::ABI::Type->new(
23             signature => $self->_remove_parent,
24             data => $item
25             );
26             }
27             }
28              
29             sub encode {
30 41     41 1 71 my $self = shift;
31              
32 41 100       133 return $self->_encoded if $self->_encoded;
33              
34 18         51 my $length = scalar $self->{data}->@*;
35             # for dynamic length arrays the length must be included
36 18 100       52 $self->_push_static($self->_encode_length($length))
37             unless $self->fixed_length;
38              
39 18 100 100     47 croak "Invalid array size, signature @{[$self->fixed_length]}, data: $length"
  1         3  
40             if $self->fixed_length && $length > $self->fixed_length;
41              
42 17         113 my $offset = $self->_get_initial_offset;
43              
44 17         45 for my $instance ($self->{instances}->@*) {
45 50 100       131 $self->_push_static($self->_encode_offset($offset))
46             if $instance->is_dynamic;
47              
48 50         113 $self->_push_dynamic($instance->encode);
49 50         117 $offset += scalar $instance->encode()->@*;
50             }
51              
52 17         84 return $self->_encoded;
53             }
54              
55             sub decode {
56 4     4 1 5 my $self = shift;
57              
58 4         12 my @data = $self->{data}->@*;
59              
60 4   66     9 my $size = $self->fixed_length // hex shift $self->{data}->@*;
61 4         17 push $self->{instances}->@*, Blockchain::Ethereum::ABI::Type->new(signature => $self->_remove_parent) for 0 .. $size - 1;
62              
63 4         35 return $self->_read_stack_set_data;
64             }
65              
66             sub _remove_parent {
67 79     79   132 my $self = shift;
68              
69 79         303 $self->{signature} =~ /(\[(\d+)?\]$)/;
70 79   100     503 return substr $self->{signature}, 0, length($self->{signature}) - length($1 // '');
71             }
72              
73             sub fixed_length {
74 47     47 1 76 my $self = shift;
75              
76 47 50       219 if ($self->{signature} =~ /\[(\d+)?\]$/) {
77 47         12932 return $1;
78             }
79 0         0 return undef;
80             }
81              
82             sub _static_size {
83 2     2   3 my $self = shift;
84              
85 2 50       3 return 1 if $self->is_dynamic;
86              
87 2         4 my $size = $self->fixed_length;
88              
89 2         3 my $instance_size = 1;
90 2         3 for my $instance ($self->{instances}->@*) {
91 0         0 $instance_size += $instance->_static_size;
92             }
93              
94 2         5 return $size * $instance_size;
95             }
96              
97             1;
98              
99             __END__