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   2797 use v5.26;
  5         18  
4 5     5   31 use strict;
  5         11  
  5         110  
5 5     5   55 use warnings;
  5         14  
  5         175  
6 5     5   39 no indirect;
  5         11  
  5         38  
7              
8 5     5   280 use Carp;
  5         11  
  5         409  
9 5     5   33 use parent qw(Blockchain::Contract::Solidity::ABI::Type);
  5         12  
  5         50  
10              
11             sub configure {
12 20     20 0 40 my $self = shift;
13 20 100       64 return unless $self->data;
14              
15 17         50 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 83 my $self = shift;
26 39 100       105 return $self->encoded if $self->encoded;
27              
28 17         49 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     57 croak "Invalid array size, signature @{[$self->fixed_length]}, data: $length"
  1         8  
34             if $self->fixed_length && $length > $self->fixed_length;
35              
36 16         77 my $offset = $self->get_initial_offset();
37              
38 16         43 for my $instance ($self->instances->@*) {
39 32 100       85 $self->push_static($self->encode_offset($offset))
40             if $instance->is_dynamic;
41              
42 32         91 $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 11 my $self = shift;
51 3         9 my @data = $self->data->@*;
52              
53 3   66     14 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         44 return $self->read_stack_set_data;
57             }
58              
59             sub remove_parent {
60 43     43 0 77 my $self = shift;
61 43         111 $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 104 my $self = shift;
67 44 50       109 if ($self->signature =~ /\[(\d+)?\]$/) {
68 44         507 return $1;
69             }
70 0         0 return undef;
71             }
72              
73             sub static_size {
74 2     2 0 6 my $self = shift;
75 2 50       7 return 1 if $self->is_dynamic;
76              
77 2         6 my $size = $self->fixed_length;
78              
79 2         7 my $instance_size = 1;
80 2         8 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