XS(ffi_pl_record_accessor_[% ffi_type %])
{
ffi_pl_record_member *member;
SV *self;
char *ptr1;
[% c_type %] *ptr2;
dVAR; dXSARGS;
if(items == 0)
croak("This is a method, you must provide at least the object");
member = (ffi_pl_record_member*) CvXSUBANY(cv).any_ptr;
self = ST(0);
if(SvROK(self))
self = SvRV(self);
if(!SvOK(self))
croak("Null record error");
ptr1 = (char*) SvPV_nolen(self);
ptr2 = ([% c_type %]*) &ptr1[member->offset];
if(items > 1)
{
if(SvREADONLY(self))
{
croak("record is read-only");
}
else
{
*ptr2 = ([% c_type %]) Sv[% perl_type %](ST(1));
}
}
if(GIMME_V == G_VOID)
XSRETURN_EMPTY;
XSRETURN_[% perl_type %](*ptr2);
}
XS(ffi_pl_record_accessor_[% ffi_type %]_array)
{
ffi_pl_record_member *member;
SV *self;
SV *arg;
SV **item;
AV *av;
char *ptr1;
int i;
[% c_type %] *ptr2;
dVAR; dXSARGS;
if(items == 0)
croak("This is a method, you must provide at least the object");
member = (ffi_pl_record_member*) CvXSUBANY(cv).any_ptr;
self = ST(0);
if(SvROK(self))
self = SvRV(self);
ptr1 = (char*) SvPV_nolen(self);
ptr2 = ([% c_type %]*) &ptr1[member->offset];
if(items > 1 && SvREADONLY(self))
{
croak("record is read-only");
}
if(items > 2)
{
i = SvIV(ST(1));
if(i >= 0 && i < member->count)
{
arg = ST(2);
ptr2[i] = Sv[% perl_type %](arg);
}
else
{
warn("illegal index %d", i);
}
}
else if(items > 1)
{
arg = ST(1);
if(SvROK(arg) && SvTYPE(SvRV(arg)) == SVt_PVAV)
{
av = (AV*) SvRV(arg);
for(i=0; i < member->count; i++)
{
item = av_fetch(av, i, 0);
if(item != NULL && SvOK(*item))
{
ptr2[i] = Sv[% perl_type %](*item);
}
else
{
ptr2[i] = [% zero %];
}
}
}
else
{
i = SvIV(ST(1));
if(i >= 0 && i < member->count)
{
XSRETURN_[% perl_type %](ptr2[i]);
}
else
{
warn("illegal index %d", i);
XSRETURN_EMPTY;
}
}
}
if(GIMME_V == G_VOID)
XSRETURN_EMPTY;
av = newAV();
av_fill(av, member->count-1);
for(i=0; i < member->count; i++)
{
sv_set[% perl_type | lower %](*av_fetch(av, i, 1), ptr2[i]);
}
ST(0) = newRV_inc((SV*)av);
XSRETURN(1);
}