AnyEvent-XMPP

 view release on metacpan or  search on metacpan

lib/AnyEvent/XMPP/Parser.pm  view on Meta::CPAN

}

=item B<set_stream_cb ($cb)>

This method sets the stream tag callback. It is called
when the <stream> tag from the server has been encountered.
The first argument to the callback is the L<AnyEvent::XMPP::Node>
of the opening stream tag.

=cut

sub set_stream_cb {
   my ($self, $cb) = @_;
   $self->{stream_cb} = $cb;
}

=item B<init>

This methods (re)initializes the parser.

=cut

sub init {
   my ($self) = @_;
   $self->{parser} = XML::Parser::ExpatNB->new (
      Namespaces => 1,
      ProtocolEncoding => 'UTF-8'
   );
   $self->{parser}->setHandlers (
      Start => sub { $self->cb_start_tag (@_) },
      End   => sub { $self->cb_end_tag   (@_) },
      Char  => sub { $self->cb_char_data (@_) },
      Default    => sub { $self->cb_default (@_) },
   );
   $self->{nso} = {};
   $self->{nodestack} = [];
}

=item B<cleanup>

This methods removes all handlers. Use it to avoid circular references.

=cut

sub cleanup {
   my ($self) = @_;

   for (qw(stanza_cb error_cb stream_cb parser)) {
      delete $self->{$_};
   }

   return;
}

=item B<nseq ($namespace, $tagname, $cmptag)>

This method checks whether the C<$cmptag> matches the C<$tagname>
in the C<$namespace>.

C<$cmptag> needs to come from the XML::Parser::Expat as it has
some magic attached that stores the namespace.

=cut

sub nseq {
   my ($self, $ns, $name, $tag) = @_;

   unless (exists $self->{nso}->{$ns}->{$name}) {
      $self->{nso}->{$ns}->{$name} =
         $self->{parser}->generate_ns_name ($name, $ns);
   }

   return $self->{parser}->eq_name ($self->{nso}->{$ns}->{$name}, $tag);
}

=item B<feed ($data)>

This method feeds a chunk of unparsed data to the parser.

=cut

sub feed {
   my ($self, $data) = @_;
   eval {
      $self->{parser}->parse_more ($data);
   };
   if ($@) {
      if ($self->{error_cb}) {
         $self->{error_cb}->($@, $data, 'xml');
      } else {
         warn "parser error: $@ on [$data]\n";
      }
   }
}

sub cb_start_tag {
   my ($self, $p, $el, %attrs) = @_;
   my $node = AnyEvent::XMPP::Node->new ($p->namespace ($el), $el, \%attrs, $self);
   $node->append_raw ($p->recognized_string);
   if (not @{$self->{nodestack}}) {
      $self->{stream_cb}->($node);
   }
   push @{$self->{nodestack}}, $node;
}

sub cb_char_data {
   my ($self, $p, $str) = @_;
   unless (@{$self->{nodestack}}) {
      warn "characters outside of tag: [$str]!\n";
      return;
   }

   return if @{$self->{nodestack}} < 2; # don't append anything to the stream element

   my $node = $self->{nodestack}->[-1];
   $node->add_text ($str);
   $node->append_raw ($p->recognized_string);
}

sub cb_end_tag {
   my ($self, $p, $el) = @_;



( run in 0.787 second using v1.01-cache-2.11-cpan-e1769b4cff6 )