File Coverage

blib/lib/Blockchain/Ethereum/ABI/Type/Array.pm
Criterion Covered Total %
statement 41 43 95.3
branch 12 14 85.7
condition 6 8 75.0
subroutine 9 9 100.0
pod 3 3 100.0
total 71 77 92.2


line stmt bran cond sub pod time code
1 6     6   4127 use v5.26;
  6         23  
2 6     6   39 use Object::Pad;
  6         14  
  6         42  
3              
4             package Blockchain::Ethereum::ABI::Type::Array 0.012;
5             class Blockchain::Ethereum::ABI::Type::Array
6             :isa(Blockchain::Ethereum::ABI::Type)
7             :does(Blockchain::Ethereum::ABI::TypeRole);
8              
9             =encoding utf8
10              
11             =head1 NAME
12              
13             Blockchain::Ethereum::ABI::Array - Interface for solidity array type
14              
15             =head1 SYNOPSIS
16              
17             Allows you to define and instantiate a solidity tuple type:
18              
19             my $type = Blockchain::Ethereum::ABI::Array->new(
20             signature => $signature,
21             data => $value
22             );
23              
24             $type->encode();
25              
26             In most cases you don't want to use this directly, use instead:
27              
28             =over 4
29              
30             =item * B: L
31              
32             =item * B: L
33              
34             =back
35              
36             =cut
37              
38 6     6   2383 use Carp;
  6         13  
  6         9984  
39              
40 20     20   54 method _configure {
41              
42 20 100       75 return unless $self->data;
43              
44 17         53 for my $item ($self->data->@*) {
45 36         102 push $self->_instances->@*,
46             Blockchain::Ethereum::ABI::Type->new(
47             signature => $self->_remove_parent,
48             data => $item
49             );
50             }
51             }
52              
53             =head2 encode
54              
55             Encodes the given data to the type of the signature
56              
57             Usage:
58              
59             encode() -> encoded string
60              
61             =over 4
62              
63             =back
64              
65             ABI encoded hex string
66              
67             =cut
68              
69 39     39 1 80 method encode {
70              
71 39 100       93 return $self->_encoded if $self->_encoded;
72              
73 17         49 my $length = scalar $self->data->@*;
74             # for dynamic length arrays the length must be included
75 17 100       52 $self->_push_static($self->_encode_length($length))
76             unless $self->fixed_length;
77              
78 17 100 100     44 croak "Invalid array size, signature @{[$self->fixed_length]}, data: $length"
  1         3  
79             if $self->fixed_length && $length > $self->fixed_length;
80              
81 16         55 my $offset = $self->_get_initial_offset;
82              
83 16         41 for my $instance ($self->_instances->@*) {
84 32 100       99 $self->_push_static($self->_encode_offset($offset))
85             if $instance->is_dynamic;
86              
87 32         104 $self->_push_dynamic($instance->encode);
88 32         80 $offset += scalar $instance->encode()->@*;
89             }
90              
91 16         35 return $self->_encoded;
92             }
93              
94             =head2 decode
95              
96             Decodes the given data to the type of the signature
97              
98             Usage:
99              
100             decoded() -> array reference
101              
102             =over 4
103              
104             =back
105              
106             Array reference
107              
108             =cut
109              
110 3     3 1 7 method decode {
111              
112 3         7 my @data = $self->data->@*;
113              
114 3   66     7 my $size = $self->fixed_length // shift $self->data->@*;
115 3         15 push $self->_instances->@*, Blockchain::Ethereum::ABI::Type->new(signature => $self->_remove_parent) for 0 .. $size - 1;
116              
117 3         31 return $self->_read_stack_set_data;
118             }
119              
120 43     43   86 method _remove_parent {
121              
122 43         106 $self->signature =~ /(\[(\d+)?\]$)/;
123 43   50     114 return substr $self->signature, 0, length($self->signature) - length($1 // '');
124             }
125              
126 44     44 1 89 method fixed_length :override {
127              
128 44 50       102 if ($self->signature =~ /\[(\d+)?\]$/) {
129 44         476 return $1;
130             }
131 0         0 return undef;
132             }
133              
134 2     2   5 method _static_size :override {
135              
136 2 50       5 return 1 if $self->is_dynamic;
137              
138 2         5 my $size = $self->fixed_length;
139              
140 2         4 my $instance_size = 1;
141 2         8 for my $instance ($self->_instances->@*) {
142 0         0 $instance_size += $instance->_static_size;
143             }
144              
145 2         5 return $size * $instance_size;
146             }
147              
148             1;
149              
150             __END__