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   2869 use v5.26;
  5         20  
4 5     5   32 use strict;
  5         12  
  5         127  
5 5     5   39 use warnings;
  5         14  
  5         126  
6 5     5   24 no indirect;
  5         11  
  5         27  
7              
8 5     5   279 use Carp;
  5         12  
  5         409  
9 5     5   34 use parent qw(REFECO::Blockchain::Contract::Solidity::ABI::Type);
  5         12  
  5         27  
10              
11             sub configure {
12 20     20 0 58 my $self = shift;
13 20 100       68 return unless $self->data;
14              
15 17         47 for my $item ($self->data->@*) {
16 36         101 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 81 my $self = shift;
26 39 100       105 return $self->encoded if $self->encoded;
27              
28 17         61 my $length = scalar $self->data->@*;
29             # for dynamic length arrays the length must be included
30 17 100       47 $self->push_static($self->encode_length($length))
31             unless $self->fixed_length;
32              
33 17 100 100     49 croak "Invalid array size, signature @{[$self->fixed_length]}, data: $length"
  1         5  
34             if $self->fixed_length && $length > $self->fixed_length;
35              
36 16         67 my $offset = $self->get_initial_offset();
37              
38 16         56 for my $instance ($self->instances->@*) {
39 32 100       78 $self->push_static($self->encode_offset($offset))
40             if $instance->is_dynamic;
41              
42 32         85 $self->push_dynamic($instance->encode);
43 32         94 $offset += scalar $instance->encode()->@*;
44             }
45              
46 16         43 return $self->encoded;
47             }
48              
49             sub decode {
50 3     3 0 7 my $self = shift;
51 3         10 my @data = $self->data->@*;
52              
53 3   66     7 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 81 my $self = shift;
61 43         113 $self->signature =~ /(\[(\d+)?\]$)/;
62 43   50     122 return substr $self->signature, 0, length($self->signature) - length($1 // '');
63             }
64              
65             sub fixed_length {
66 44     44 0 90 my $self = shift;
67 44 50       119 if ($self->signature =~ /\[(\d+)?\]$/) {
68 44         468 return $1;
69             }
70 0         0 return undef;
71             }
72              
73             sub static_size {
74 2     2 0 4 my $self = shift;
75 2 50       6 return 1 if $self->is_dynamic;
76              
77 2         5 my $size = $self->fixed_length;
78              
79 2         4 my $instance_size = 1;
80 2         10 for my $instance ($self->instances->@*) {
81 0         0 $instance_size += $instance->static_size;
82             }
83              
84 2         8 return $size * $instance_size;
85             }
86              
87             1;
88