FFI-C
view release on metacpan or search on metacpan
lib/FFI/C/Struct.pm view on Meta::CPAN
package FFI::C::Struct;
use strict;
use warnings;
use FFI::C::Util;
use FFI::C::FFI ();
use Ref::Util qw( is_ref is_plain_arrayref );
# ABSTRACT: Structured data instance for FFI
our $VERSION = '0.15'; # VERSION
sub AUTOLOAD
{
our $AUTOLOAD;
my $self = shift;
my $name = $AUTOLOAD;
$name=~ s/^.*:://;
if(my $member = $self->{def}->{members}->{$name})
{
my $ptr = $self->{ptr} + $member->{offset};
if($member->{nest})
{
my $m = $member->{nest}->create($ptr,$self->{owner} || $self);
FFI::C::Util::perl_to_c($m, $_[0]) if @_;
return $m;
}
my $ffi = $self->{def}->ffi;
if(defined $member->{count})
{
if(defined $_[0])
{
if(! is_ref $_[0])
{
my $index = shift;
Carp::croak("$name Negative index on array member") if $index < 0;
Carp::croak("$name OOB index on array member") if $index >= $member->{count};
$ptr += $index * $member->{unitsize};
}
elsif(is_plain_arrayref $_[0])
{
my $array = shift;
Carp::croak("$name OOB index on array member") if @$array > $member->{count};
my $asize = @$array * $member->{unitsize};
$ffi->function( FFI::C::FFI::memcpy_addr() => [ 'opaque', $member->{spec} . "[@{[ scalar @$array ]}]", 'size_t' ] => 'opaque' )
->call($ptr, $array, $asize);
my @a;
tie @a, 'FFI::C::Struct::MemberArrayTie', $self, $name, $member->{count};
return \@a;
}
else
{
Carp::croak("$name tried to set element to non-scalar");
}
}
else
{
my @a;
tie @a, 'FFI::C::Struct::MemberArrayTie', $self, $name, $member->{count};
return \@a;
}
}
if(@_)
( run in 1.012 second using v1.01-cache-2.11-cpan-39bf76dae61 )