File Coverage

blib/lib/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 Blockchain::Contract::Solidity::ABI::Type::Array;
2              
3 5     5   2784 use v5.26;
  5         21  
4 5     5   30 use strict;
  5         12  
  5         117  
5 5     5   27 use warnings;
  5         10  
  5         125  
6 5     5   25 no indirect;
  5         12  
  5         27  
7              
8 5     5   311 use Carp;
  5         19  
  5         431  
9 5     5   35 use parent qw(Blockchain::Contract::Solidity::ABI::Type);
  5         19  
  5         35  
10              
11             sub configure {
12 20     20 0 37 my $self = shift;
13 20 100       60 return unless $self->data;
14              
15 17         55 for my $item ($self->data->@*) {
16 36         102 push $self->instances->@*,
17             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       102 return $self->encoded if $self->encoded;
27              
28 17         58 my $length = scalar $self->data->@*;
29             # for dynamic length arrays the length must be included
30 17 100       39 $self->push_static($self->encode_length($length))
31             unless $self->fixed_length;
32              
33 17 100 100     63 croak "Invalid array size, signature @{[$self->fixed_length]}, data: $length"
  1         3  
34             if $self->fixed_length && $length > $self->fixed_length;
35              
36 16         58 my $offset = $self->get_initial_offset();
37              
38 16         51 for my $instance ($self->instances->@*) {
39 32 100       81 $self->push_static($self->encode_offset($offset))
40             if $instance->is_dynamic;
41              
42 32         88 $self->push_dynamic($instance->encode);
43 32         82 $offset += scalar $instance->encode()->@*;
44             }
45              
46 16         51 return $self->encoded;
47             }
48              
49             sub decode {
50 3     3 0 7 my $self = shift;
51 3         7 my @data = $self->data->@*;
52              
53 3   66     7 my $size = $self->fixed_length // shift $self->data->@*;
54 3         15 push $self->instances->@*, Blockchain::Contract::Solidity::ABI::Type::new_type(signature => $self->remove_parent) for 0 .. $size - 1;
55              
56 3         21 return $self->read_stack_set_data;
57             }
58              
59             sub remove_parent {
60 43     43 0 87 my $self = shift;
61 43         113 $self->signature =~ /(\[(\d+)?\]$)/;
62 43   50     114 return substr $self->signature, 0, length($self->signature) - length($1 // '');
63             }
64              
65             sub fixed_length {
66 44     44 0 73 my $self = shift;
67 44 50       119 if ($self->signature =~ /\[(\d+)?\]$/) {
68 44         531 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         4 my $instance_size = 1;
80 2         9 for my $instance ($self->instances->@*) {
81 0         0 $instance_size += $instance->static_size;
82             }
83              
84 2         5 return $size * $instance_size;
85             }
86              
87             1;
88