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   2944 use v5.26;
  5         19  
4 5     5   30 use strict;
  5         14  
  5         108  
5 5     5   30 use warnings;
  5         10  
  5         126  
6 5     5   27 no indirect;
  5         22  
  5         42  
7              
8 5     5   311 use Carp;
  5         13  
  5         420  
9 5     5   41 use parent qw(REFECO::Blockchain::Contract::Solidity::ABI::Type);
  5         13  
  5         43  
10              
11             sub configure {
12 20     20 0 39 my $self = shift;
13 20 100       71 return unless $self->data;
14              
15 17         49 for my $item ($self->data->@*) {
16 36         100 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 73 my $self = shift;
26 39 100       117 return $self->encoded if $self->encoded;
27              
28 17         54 my $length = scalar $self->data->@*;
29             # for dynamic length arrays the length must be included
30 17 100       41 $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         3  
34             if $self->fixed_length && $length > $self->fixed_length;
35              
36 16         70 my $offset = $self->get_initial_offset();
37              
38 16         59 for my $instance ($self->instances->@*) {
39 32 100       80 $self->push_static($self->encode_offset($offset))
40             if $instance->is_dynamic;
41              
42 32         94 $self->push_dynamic($instance->encode);
43 32         83 $offset += scalar $instance->encode()->@*;
44             }
45              
46 16         45 return $self->encoded;
47             }
48              
49             sub decode {
50 3     3 0 7 my $self = shift;
51 3         8 my @data = $self->data->@*;
52              
53 3   66     9 my $size = $self->fixed_length // shift $self->data->@*;
54 3         15 push $self->instances->@*, REFECO::Blockchain::Contract::Solidity::ABI::Type::new_type(signature => $self->remove_parent) for 0 .. $size - 1;
55              
56 3         20 return $self->read_stack_set_data;
57             }
58              
59             sub remove_parent {
60 43     43 0 85 my $self = shift;
61 43         115 $self->signature =~ /(\[(\d+)?\]$)/;
62 43   50     118 return substr $self->signature, 0, length($self->signature) - length($1 // '');
63             }
64              
65             sub fixed_length {
66 44     44 0 92 my $self = shift;
67 44 50       120 if ($self->signature =~ /\[(\d+)?\]$/) {
68 44         447 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         7 return $size * $instance_size;
85             }
86              
87             1;
88