Class-Accessor-Fast-GXS
view release on metacpan or search on metacpan
lib/Class/Accessor/Fast/GXS.pm view on Meta::CPAN
END
my %failed_loads = ();
sub __xs_load_or_fallback_to_super {
my $self = shift;
my $method = 'SUPER::'. shift;
my $field = shift;
my $name = shift;
my $class = ref $self || $self;
no strict 'refs';
return \&{"${class}::__xs_$name"}
if defined &{"${class}::__xs_$name"};
my @parts = split /::/, $class;
my $found = 0;
do {
local $@;
my $module = join "::", @parts;
if ( $failed_loads{$module} || !eval { require XSLoader; XSLoader::load($module); 1 } ) {
$failed_loads{$module} = 1;
} else {
$found = 1;
}
pop @parts;
} while @parts;
unless ( $found ) {
warn "not found dynamic library for $class" if $DEBUG;
return $self->$method($field, @_);
}
return \&{"${class}::__xs_$name"}
if defined &{"${class}::__xs_$name"};
warn "C lib has no $name in $class" if $DEBUG;
return $self->$method($field, @_);
}
my %handles = ();
sub __get_handle_for_xs {
my $self = shift;
my $class = ref $self || $self;
my $module = $MODULE || $class;
my $fh = $handles{ $module };
return $fh if $fh;
my $fn = $GENERATE_TO;
$fn = join '/', $GENERATE_TO, split /::/, $module .".xs"
if -d $GENERATE_TO;
open $fh, ">", $fn or die "couldn't open file '$fn': $!";
$handles{ $module } = $fh;
print $fh $head, "\n\n";
return $fh;
}
# XXX: escaping and unicode support
my %done = ();
sub make_ro_accessor {
my $self = shift;
my $field = shift;
my $name = $self->accessor_name_for($field);
return $self->__xs_load_or_fallback_to_super('make_ro_accessor', $name, $field, @_)
unless defined $GENERATE_TO;
my $class = ref $self || $self;
return if $done{$class."::".$name}++;
warn "making $field ro accessor for $class" if $DEBUG;
my $fh = $self->__get_handle_for_xs;
print $fh "MODULE = ". ($MODULE||$class) ." PACKAGE = $class\n\n";
my $length = length $field;
print $fh <<END;
void
__xs_$name(self)
SV* self;
PROTOTYPE: DISABLE
INIT:
SV** res;
PPCODE:
res = hv_fetch((HV *)SvRV(self), "$field", $length, 0);
if (res == NULL)
XSRETURN_UNDEF;
XPUSHs(*res);
END
return undef;
}
sub make_wo_accessor {
my $self = shift;
my $field = shift;
my $name = $self->mutator_name_for($field);
return $self->__xs_load_or_fallback_to_super('make_wo_accessor', $name, $field, @_)
unless defined $GENERATE_TO;
my $class = ref $self || $self;
return if $done{$class."::".$name}++;
warn "making $field wo accessor for $class" if $DEBUG;
my $fh = $self->__get_handle_for_xs;
print $fh "MODULE = ". ($MODULE||$class) ." PACKAGE = $class\n\n";
my $length = length $field;
print $fh <<END;
void
__xs_$name(self, ...)
SV* self;
PROTOTYPE: DISABLE
INIT:
SV **res;
( run in 0.645 second using v1.01-cache-2.11-cpan-39bf76dae61 )