Bit::MorseSignals::Receiver - Base class for Bit::MorseSignals receivers.


Bit-MorseSignals documentation Contained in the Bit-MorseSignals distribution.

Index


Code Index:

NAME

Top

Bit::MorseSignals::Receiver - Base class for Bit::MorseSignals receivers.

VERSION

Top

Version 0.06

SYNOPSIS

Top

    use Bit::MorseSignals::Receiver;

    my $pants = new Bit::MorseSignals::Receiver done => sub { print "received $_[1]!\n" };
    while (...) {
     my $bit = comes_from_somewhere_lets_say_signals();
     $pants->push($bit);
    }

DESCRIPTION

Top

Base class for Bit::MorseSignals receivers. Please refer to this module for more general information about the protocol.

Given a sequence of bits coming from the Bit::MorseSignals protocol, the receiver object detects when a packet has been completed and then reconstructs the original message depending of the datatype specified in the header.

METHODS

Top

new < done => $cb >

Bit::MorseSignals::Receiver object constructor. With the 'done' option, you can specify a callback that will be triggered every time a message is completed, and in which $_[0] will be the receiver object and $_[1] the message received.

push $bit

Tells the receiver that you have received the bit $bit. Returns true while the message isn't completed, and undef as soon as it is.

reset

Resets the current receiver state, obliterating any current message being received.

busy

True when the receiver is in the middle of assembling a message.

msg

The last message completed, or undef when no message has been assembled yet.

EXPORT

Top

An object module shouldn't export any function, and so does this one.

DEPENDENCIES

Top

Carp (standard since perl 5), Encode (since perl 5.007003), Storable (idem).

SEE ALSO

Top

Bit::MorseSignals, Bit::MorseSignals::Emitter.

AUTHOR

Top

Vincent Pit, <perl at profvince.com>, http://www.profvince.com.

You can contact me by mail or on #perl @ FreeNode (vincent or Prof_Vince).

BUGS

Top

Please report any bugs or feature requests to bug-bit-morsesignals-receiver at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Bit-MorseSignals. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

Top

You can find documentation for this module with the perldoc command.

    perldoc Bit::MorseSignals::Receiver

Tests code coverage report is available at http://www.profvince.com/perl/cover/Bit-MorseSignals.

COPYRIGHT & LICENSE

Top


Bit-MorseSignals documentation Contained in the Bit-MorseSignals distribution.
package Bit::MorseSignals::Receiver;

use strict;
use warnings;

use Carp qw/croak/;
use Encode qw/decode_utf8/;
use Storable qw/thaw/;

use Bit::MorseSignals qw/:consts/;

our $VERSION = '0.06';

sub _check_self {
 croak 'First argument isn\'t a valid ' . __PACKAGE__ . ' object'
  unless ref $_[0] and $_[0]->isa(__PACKAGE__);
}

sub new {
 my $class = shift;
 return unless $class = ref $class || $class;
 croak 'Optional arguments must be passed as key => value pairs' if @_ % 2;
 my %opts = @_;
 my $self = {
  msg    => undef,
  done   => $opts{done},
 };
 bless $self, $class;
 $self->reset;
 return $self;
}

sub push {
 my ($self, $bit) = @_;
 _check_self($self);
 if (!defined $bit) {
  $bit = $_;
  return unless defined $bit;
 }
 $bit = $bit ? 1 : 0;

 if ($self->{state} == 3) { # data

  vec($self->{buf}, $self->{len}, 1) = $bit;
  ++$self->{len};
  if ($self->{len} >= $self->{sig_len}) {
   my $res = 1;
   for (1 .. $self->{sig_len}) {
    if (vec($self->{buf}, $self->{len} - $_, 1) != vec($self->{sig}, $_-1, 1)) {
     $res = 0;
     last;
    }
   }
   if ($res) {
    my $base = int $self->{sig_len} / 8 + $self->{sig_len} % 8 != 0;
    substr $self->{buf}, -$base, $base, '';
    my @demanglers = (sub { $_[0] }, \&decode_utf8, \&thaw  );
    #        BM_DATA_{PLAIN,         UTF8,          STORABLE}
    $self->{msg} = defined $demanglers[$self->{type}]
                    ? do {
                       local $SIG{__DIE__} = sub { warn @_ };
                       $demanglers[$self->{type}]->($self->{buf})
                      }
                    : $self->{buf};
    $self->reset;
    $self->{done}->($self, $self->{msg}) if $self->{done};
    return;
   }
  }

 } elsif ($self->{state} == 2) { # header

  vec($self->{buf}, $self->{len}++, 1) = $bit;
  if ($self->{len} >= 3) {
   my $type = 2 * vec($self->{buf}, 1, 1)
                + vec($self->{buf}, 0, 1);
   $type = BM_DATA_PLAIN if vec($self->{buf}, 2, 1);
   @{$self}{qw/state type buf len/} = (3, $type, '', 0);
  }

 } elsif ($self->{state} == 1) { # end of signature

  if ($self->{sig_bit} != $bit) {
   $self->{state} = 2;
  }
  vec($self->{sig}, $self->{sig_len}++, 1) = $bit;

 } else { # first bit

  @{$self}{qw/state sig sig_bit sig_len buf len/}
           = (1,    '', $bit,   1,      '', 0  );
  vec($self->{sig}, 0, 1) = $bit;

 }

 return $self;
}

sub reset {
 my ($self) = @_;
 _check_self($self);
 $self->{state} = 0;
 @{$self}{qw/sig sig_bit sig_len type buf len/} = ();
 return $self;
}

sub busy {
 my ($self) = @_;
 _check_self($self);
 return $self->{state} > 0;
}

sub msg {
 my ($self) = @_;
 _check_self($self);
 return $self->{msg};
}

1; # End of Bit::MorseSignals::Receiver