line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package FFI::C::ArrayDef; |
2
|
|
|
|
|
|
|
|
3
|
4
|
|
|
4
|
|
1118
|
use strict; |
|
4
|
|
|
|
|
10
|
|
|
4
|
|
|
|
|
96
|
|
4
|
4
|
|
|
4
|
|
16
|
use warnings; |
|
4
|
|
|
|
|
17
|
|
|
4
|
|
|
|
|
75
|
|
5
|
4
|
|
|
4
|
|
52
|
use 5.008001; |
|
4
|
|
|
|
|
28
|
|
6
|
4
|
|
|
4
|
|
411
|
use Ref::Util qw( is_blessed_ref is_ref is_plain_arrayref ); |
|
4
|
|
|
|
|
1397
|
|
|
4
|
|
|
|
|
198
|
|
7
|
4
|
|
|
4
|
|
1408
|
use FFI::C::Array; |
|
4
|
|
|
|
|
9
|
|
|
4
|
|
|
|
|
88
|
|
8
|
4
|
|
|
4
|
|
388
|
use Sub::Install (); |
|
4
|
|
|
|
|
1449
|
|
|
4
|
|
|
|
|
51
|
|
9
|
4
|
|
|
4
|
|
374
|
use Sub::Util (); |
|
4
|
|
|
|
|
262
|
|
|
4
|
|
|
|
|
82
|
|
10
|
4
|
|
|
4
|
|
18
|
use Scalar::Util qw( refaddr ); |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
156
|
|
11
|
4
|
|
|
4
|
|
32
|
use base qw( FFI::C::Def ); |
|
4
|
|
|
|
|
12
|
|
|
4
|
|
|
|
|
1841
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
our @CARP_NOT = qw( FFI::C ); |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
# ABSTRACT: Array data definition for FFI |
16
|
|
|
|
|
|
|
our $VERSION = '0.12'; # VERSION |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
sub new |
20
|
|
|
|
|
|
|
{ |
21
|
11
|
|
|
11
|
1
|
1017
|
my $self = shift->SUPER::new(@_); |
22
|
|
|
|
|
|
|
|
23
|
11
|
|
|
|
|
18
|
my %args = %{ delete $self->{args} }; |
|
11
|
|
|
|
|
43
|
|
24
|
|
|
|
|
|
|
|
25
|
11
|
|
|
|
|
23
|
my $member; |
26
|
11
|
|
|
|
|
18
|
my $count = 0; |
27
|
|
|
|
|
|
|
|
28
|
11
|
50
|
|
|
|
14
|
my @members = @{ delete $args{members} || [] }; |
|
11
|
|
|
|
|
40
|
|
29
|
11
|
100
|
|
|
|
36
|
if(@members == 1) |
|
|
50
|
|
|
|
|
|
30
|
|
|
|
|
|
|
{ |
31
|
4
|
|
|
|
|
7
|
($member) = @members; |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
elsif(@members == 2) |
34
|
|
|
|
|
|
|
{ |
35
|
7
|
|
|
|
|
17
|
($member, $count) = @members; |
36
|
|
|
|
|
|
|
} |
37
|
|
|
|
|
|
|
else |
38
|
|
|
|
|
|
|
{ |
39
|
0
|
|
|
|
|
0
|
Carp::croak("The members argument should be a struct/union type and an optional element count"); |
40
|
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
|
42
|
11
|
100
|
|
|
|
35
|
if(my $def = $self->ffi->def('FFI::C::Def', $member)) |
43
|
|
|
|
|
|
|
{ |
44
|
4
|
|
|
|
|
33
|
$member = $def; |
45
|
|
|
|
|
|
|
} |
46
|
|
|
|
|
|
|
|
47
|
11
|
100
|
|
|
|
211
|
Carp::croak("Canot nest an array def inside of itself") if refaddr($member) == refaddr($self); |
48
|
|
|
|
|
|
|
|
49
|
10
|
50
|
33
|
|
|
77
|
Carp::croak("Illegal member") |
|
|
|
33
|
|
|
|
|
50
|
|
|
|
|
|
|
unless defined $member && is_blessed_ref($member) && $member->isa("FFI::C::Def"); |
51
|
|
|
|
|
|
|
|
52
|
10
|
50
|
33
|
|
|
65
|
Carp::croak("The element count must be a positive integer") |
53
|
|
|
|
|
|
|
if defined $count && $count !~ /^[1-9]*[0-9]$/; |
54
|
|
|
|
|
|
|
|
55
|
10
|
|
|
|
|
33
|
$self->{size} = $member->size * $count; |
56
|
10
|
|
|
|
|
28
|
$self->{align} = $member->align; |
57
|
10
|
|
|
|
|
23
|
$self->{members}->{member} = $member; |
58
|
10
|
|
|
|
|
18
|
$self->{members}->{count} = $count; |
59
|
|
|
|
|
|
|
|
60
|
10
|
|
|
|
|
31
|
Carp::carp("Unknown argument: $_") for sort keys %args; |
61
|
|
|
|
|
|
|
|
62
|
10
|
100
|
|
|
|
28
|
if($self->class) |
63
|
|
|
|
|
|
|
{ |
64
|
|
|
|
|
|
|
# not handled by the superclass: |
65
|
|
|
|
|
|
|
# 3. Any nested cdefs must have Perl classes. |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
{ |
68
|
5
|
|
|
|
|
9
|
my $member = $self->{members}->{member}; |
|
5
|
|
|
|
|
9
|
|
69
|
5
|
|
|
|
|
11
|
my $accessor = $self->class . '::get'; |
70
|
|
|
|
|
|
|
Carp::croak("Missing Perl class for $accessor") |
71
|
5
|
50
|
33
|
|
|
17
|
if $member->{nest} && !$member->{nest}->{class}; |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
|
74
|
5
|
|
|
|
|
25
|
$self->_generate_class(qw( get )); |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
{ |
77
|
5
|
|
|
|
|
16
|
my $member_class = $self->{members}->{member}->class; |
78
|
5
|
|
|
|
|
48
|
my $member_size = $self->{members}->{member}->size; |
79
|
|
|
|
|
|
|
my $code = sub { |
80
|
61
|
|
|
28
|
|
8190
|
my($self, $index) = @_; |
|
|
|
|
28
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
27
|
|
|
|
81
|
61
|
100
|
|
|
|
356
|
Carp::croak("Negative array index") if $index < 0; |
82
|
57
|
100
|
100
|
|
|
595
|
Carp::croak("OOB array index") if $self->{count} && $index >= $self->{count}; |
83
|
53
|
|
|
|
|
121
|
my $ptr = $self->{ptr} + $member_size * $index; |
84
|
53
|
|
|
|
|
110
|
$member_class->new($ptr,$self); |
85
|
5
|
|
|
|
|
52
|
}; |
86
|
5
|
|
|
|
|
13
|
Sub::Util::set_subname(join('::', $self->class), $code); |
87
|
5
|
|
|
|
|
30
|
Sub::Install::install_sub({ |
88
|
|
|
|
|
|
|
code => $code, |
89
|
|
|
|
|
|
|
into => $self->class, |
90
|
|
|
|
|
|
|
as => 'get', |
91
|
|
|
|
|
|
|
}); |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
{ |
95
|
4
|
|
|
4
|
|
43
|
no strict 'refs'; |
|
4
|
|
|
|
|
9
|
|
|
4
|
|
|
|
|
1193
|
|
|
5
|
|
|
|
|
170
|
|
|
5
|
|
|
|
|
191
|
|
96
|
5
|
|
|
|
|
39
|
push @{ join '::', $self->class, 'ISA' }, 'FFI::C::Array'; |
|
5
|
|
|
|
|
15
|
|
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
|
101
|
10
|
|
|
|
|
51
|
$self; |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
sub create |
106
|
|
|
|
|
|
|
{ |
107
|
7
|
|
|
7
|
1
|
277
|
my $self = shift; |
108
|
|
|
|
|
|
|
|
109
|
7
|
50
|
|
|
|
19
|
return $self->class->new(@_) if $self->class; |
110
|
|
|
|
|
|
|
|
111
|
7
|
|
|
|
|
20
|
local $self->{size} = $self->{size}; |
112
|
7
|
|
|
|
|
15
|
my $count = $self->{members}->{count}; |
113
|
7
|
100
|
|
|
|
18
|
if(@_ == 1) |
114
|
|
|
|
|
|
|
{ |
115
|
3
|
50
|
|
|
|
22
|
if(! is_ref $_[0]) |
|
|
50
|
|
|
|
|
|
116
|
|
|
|
|
|
|
{ |
117
|
0
|
|
|
|
|
0
|
$count = shift; |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
elsif(is_plain_arrayref $_[0]) |
120
|
|
|
|
|
|
|
{ |
121
|
3
|
|
|
|
|
6
|
$count = scalar @{$_[0]}; |
|
3
|
|
|
|
|
9
|
|
122
|
|
|
|
|
|
|
} |
123
|
3
|
50
|
|
|
|
8
|
if($count) |
124
|
|
|
|
|
|
|
{ |
125
|
3
|
|
|
|
|
11
|
$self->{size} = $self->{members}->{member}->size * $count; |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
|
129
|
7
|
50
|
66
|
|
|
52
|
if( (@_ == 2 && ! is_ref $_[0]) || ($self->size) ) |
|
|
|
66
|
|
|
|
|
130
|
|
|
|
|
|
|
{ |
131
|
7
|
|
|
|
|
26
|
my $array = $self->SUPER::create(@_); |
132
|
7
|
|
|
|
|
81
|
$array->{count} = $count; |
133
|
7
|
100
|
66
|
|
|
41
|
FFI::C::Util::perl_to_c($array, $_[0]) if @_ == 1 && is_plain_arrayref $_[0]; |
134
|
7
|
|
|
|
|
23
|
return $array; |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
|
137
|
0
|
|
|
|
|
|
Carp::croak("Cannot create array without knowing the number of elements"); |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
1; |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
__END__ |