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/

Reply via email to