File Coverage

blib/lib/REFECO/Blockchain/Contract/Solidity/ABI/Type/Array.pm
Criterion Covered Total %
statement 50 52 96.1
branch 12 14 85.7
condition 6 8 75.0
subroutine 12 12 100.0
pod 0 6 0.0
total 80 92 86.9


line stmt bran cond sub pod time code
1             package REFECO::Blockchain::Contract::Solidity::ABI::Type::Array;
2              
3 5     5   2847 use v5.26;
  5         22  
4 5     5   30 use strict;
  5         9  
  5         122  
5 5     5   29 use warnings;
  5         12  
  5         139  
6 5     5   27 no indirect;
  5         12  
  5         28  
7              
8 5     5   301 use Carp;
  5         13  
  5         364  
9 5     5   43 use parent qw(REFECO::Blockchain::Contract::Solidity::ABI::Type);
  5         14  
  5         28  
10              
11             sub configure {
12 20     20 0 39 my $self = shift;
13 20 100       68 return unless $self->data;
14              
15 17         46 for my $item ($self->data->@*) {
16 36         104 push $self->instances->@*,
17             REFECO::Blockchain::Contract::Solidity::ABI::Type::new_type(
18             signature => $self->remove_parent,
19             data => $item
20             );
21             }
22             }
23              
24             sub encode {
25 39     39 0 74 my $self = shift;
26 39 100       109 return $self->encoded if $self->encoded;
27              
28 17         48 my $length = scalar $self->data->@*;
29             # for dynamic length arrays the length must be included
30 17 100       45 $self->push_static($self->encode_length($length))
31             unless $self->fixed_length;
32              
33 17 100 100     45 croak "Invalid array size, signature @{[$self->fixed_length]}, data: $length"
  1         4  
34             if $self->fixed_length && $length > $self->fixed_length;
35              
36 16         62 my $offset = $self->get_initial_offset();
37              
38 16         46 for my $instance ($self->instances->@*) {
39 32 100       105 $self->push_static($self->encode_offset($offset))
40             if $instance->is_dynamic;
41              
42 32         93 $self->push_dynamic($instance->encode);
43 32         80 $offset += scalar $instance->encode()->@*;
44             }
45              
46 16         50 return $self->encoded;
47             }
48              
49             sub decode {
50 3     3 0 6 my $self = shift;
51 3         9 my @data = $self->data->@*;
52              
53 3   66     10 my $size = $self->fixed_length // shift $self->data->@*;
54 3         17 push $self->instances->@*, REFECO::Blockchain::Contract::Solidity::ABI::Type::new_type(signature => $self->remove_parent) for 0 .. $size - 1;
55              
56 3         22 return $self->read_stack_set_data;
57             }
58              
59             sub remove_parent {
60 43     43 0 80 my $self = shift;
61 43         116 $self->signature =~ /(\[(\d+)?\]$)/;
62 43   50     129 return substr $self->signature, 0, length($self->signature) - length($1 // '');
63             }
64              
65             sub fixed_length {
66 44     44 0 80 my $self = shift;
67 44 50       125 if ($self->signature =~ /\[(\d+)?\]$/) {
68 44         451 return $1;
69             }
70 0         0 return undef;
71             }
72              
73             sub static_size {
74 2     2 0 5 my $self = shift;
75 2 50       5 return 1 if $self->is_dynamic;
76              
77 2         5 my $size = $self->fixed_length;
78              
79 2         5 my $instance_size = 1;
80 2         9 for my $instance ($self->instances->@*) {
81 0         0 $instance_size += $instance->static_size;
82             }
83              
84 2         6 return $size * $instance_size;
85             }
86              
87             1;
88