Zbigniew,
You should be able to do this:
package Net::Packet::EraApi;
use Moose;
use ERAAPI2Inline;
has [ qw( OpRef MsgType Operation DataSize data ) ] => (is => 'rw');
sub decode_headers {
my ( $class, $params ) = @_;
my $self = $class->new;
ERAAPI2Inline::Framedecode( $params->{packet}, $self );
return $self;
}
1;
It is not ideal as it bypasses all the Moose constructor and
initializer goodness, however since you seem to be unpacking a C
struct of some kind you wouldn't have been able to do that anyway.
- Stevan
On Jan 13, 2009, at 11:14 AM, Zbigniew Lukasiak wrote:
Thanks for all the replies,
Apparently this will take longer time - as it seems it is not the
highest priority right now - but I do find it interesting so I'll try
to continue it.
On Fri, Jan 9, 2009 at 6:58 PM, Stevan Little
<stevan.lit...@iinteractive.com> wrote:
Zbigniew,
Well, if you are creating the objects with C, this might be tricky,
but can
be worked around. If you are writing/reading data from C-based
accessors,
this is still a little tricky but easily worked around. If you just
need to
call methods which are not accessors or constructors, but are
written in C,
then this will be no problem at all.
For now I have the following:
package Net::Packet::EraApi;
use base 'Class::Accessor';
__PACKAGE__->mk_accessors(qw( OpRef MsgType Operation DataSize
data ) );
use warnings;
use strict;
use ERAAPI2Inline;
.
.
.
sub decode_headers {
my ( $class, $packet ) = @_;
my %frame;
my $f_ref = \%frame;
ERAAPI2Inline::Framedecode( $packet, $f_ref ); # this is the
Inline builder
return bless $f_ref, $class;
}
So I create the object with 'ecode_headers' and in it I add entries to
it's data hash with an Inline C function. The measurements of the
overheads need to wait - but this is what I was asked to do.
The C Inline function in ERAAPI2Inline is:
void* Framedecode(SV* packet, SV* hash_ref) {
HV* hash;
void* pkt;
STRLEN pktlen;
struct era_hdr* era_hdr;
hash = (HV*) SvRV( hash_ref );
pkt = SvPV(packet, pktlen);
era_hdr = pkt;
hv_store(hash, "OpRef", 5, newSViv(htonl(era_hdr->opref)), 0);
hv_store(hash, "MsgType", 7, newSViv(era_hdr->msgtype), 0);
hv_store(hash, "Operation", 9, newSViv((era_hdr->operation)), 0);
hv_store(hash, "DataSize", 8, newSViv((era_hdr->datasize)), 0);
if(pktlen >= era_hdr_len + era_hdr->datasize )
hv_store(hash, "data", 4, newSVpv(pkt+era_hdr_len,
pktlen-era_hdr_len), 0);
else
hv_store(hash, "data", 4, &PL_sv_undef, 0);
return;
}
Apparently with Class::Accessor this works.
I was also thinking about the Marco Fontani's and Chris Prather's
proposals of doing:
Net::Packet::EraAp->new(%{ ERAAPI2Inline::Framedecode( $packet ) } );
(with a small change to the C function) - this looks like simple
workaround and I'll need to check it. I think this would trigger the
type checkers in Moose and probably that would mean too much overhead
though.
Cheers,
Zbigniew
http://brudnopis.blogspot.com/
http://perlalchemy.blogspot.com/