/usr/local/CPAN/POE-Component-YahooMessenger/POE/Filter/YahooMessengerPacket.pm
package POE::Filter::YahooMessengerPacket;
use strict;
use POE::Component::YahooMessenger::Constants;
use POE::Component::YahooMessenger::Event;
sub new {
my $class = shift;
bless {
buffer => '',
get_state => 'header',
body_info => {},
identifier => undef,
}, $class;
}
use constant DEBUG => 0;
sub Dumper { require Data::Dumper; Data::Dumper::Dumper(@_) }
sub get {
my($self, $stream) = @_;
$self->{buffer} .= join '', @$stream;
if ($self->{get_state} eq 'header') {
# not enough header bytes
return [] if length($self->{buffer}) < 20;
my $header = substr $self->{buffer}, 0, 20, '';
my($signature, $version, $length, $event_code, $option, $identifier)
= unpack "a4Cx3nnNN", $header;
if ($signature ne $MessageHeader) {
_carp("signateure mismatch: $signature");
return [];
}
$self->{identifier} ||= $identifier;
# switch to body mode
$self->{get_state} = 'body';
$self->{body_info} = {
length => $length,
event_code => $event_code,
identifier => $identifier,
};
}
# not enough body bytes
return [] if length($self->{buffer}) < $self->{body_info}->{length};
# we have enough body bytes
my $body = substr $self->{buffer}, 0, $self->{body_info}->{length}, '';
$self->{get_state} = 'header';
my $event = POE::Component::YahooMessenger::Event->new_from_body(
$self->{body_info}->{event_code}, $body,
);
DEBUG and warn("GET: ", Dumper($event));
return [ $event ];
}
sub put {
my($self, $events) = @_;
return [ map $self->_put($_), @$events ];
}
sub _put {
my($self, $event) = @_;
DEBUG and warn("PUT: ", Dumper($event));
my $body = $event->body;
my $header = pack(
"a4Cx3nnNN",
$MessageHeader, 9, length($body), $event->code, $event->option, $self->{identifier} || 0,
);
return $header. $body;
}
1;