ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Net-XMPP2/lib/Net/XMPP2/Parser.pm
Revision: 1.2
Committed: Thu Jan 25 13:17:06 2007 UTC (19 years, 9 months ago) by elmex
Branch: MAIN
Changes since 1.1: +6 -0 lines
Log Message:
extended send_presence and send_message, untested.
wrote some documentation to XMPP.pm and Writer.pm and Parser.pm.

File Contents

# Content
1 package Net::XMPP2::Parser;
2 use warnings;
3 use strict;
4 # OMFG!!!111 THANK YOU FOR THIS MODULE TO HANDLE THE XMPP INSANITY:
5 use Net::XMPP2::Node;
6 use XML::Parser::Expat;
7
8 =head1 NAME
9
10 Net::XMPP2::Parser - A parser for XML streams (helper for Net::XMPP2)
11
12 =head1 SYNOPSIS
13
14 use Net::XMPP2::Parser;
15 ...
16
17 =head1 DESCRIPTION
18
19 This is a XMPP XML parser helper class, which helps me to cope with the XMPP XML.
20
21 See also L<Net::XMPP2::Writer> for a discussion of the issues with XML in XMPP.
22
23 =head1 METHODS
24
25 =head2 new
26
27 This creates a new Net::XMPP2::Parser and calls C<init>.
28
29 =cut
30
31 sub new {
32 my $this = shift;
33 my $class = ref($this) || $this;
34 my $self = { stanza_cb => sub { die "No stanza callback provided!" }, @_ };
35 bless $self, $class;
36 $self->init;
37 $self
38 }
39
40 =head2 set_stanza_cb ($cb)
41
42 Sets the 'XML stanza' callback.
43
44 C<$cb> must be a code reference. The first argument to
45 the callback will be this Net::XMPP2::Parser instance and
46 the second will be the stanzas root Net::XMPP2::Node as first argument.
47
48 =cut
49
50 sub set_stanza_cb {
51 my ($self, $cb) = @_;
52 $self->{stanza_cb} = $cb;
53 }
54
55 =head2 init
56
57 This methods (re)initializes the parser.
58
59 =cut
60
61 sub init {
62 my ($self) = @_;
63 $self->{parser} = XML::Parser::ExpatNB->new (
64 Namespaces => 1,
65 ProtocolEncoding => 'UTF-8'
66 );
67 $self->{parser}->setHandlers (
68 Start => sub { $self->cb_start_tag (@_) },
69 End => sub { $self->cb_end_tag (@_) },
70 Char => sub { $self->cb_char_data (@_) },
71 );
72 $self->{nso} = {};
73 $self->{nodestack} = [];
74 }
75
76 =head2 nseq ($namespace, $tagname, $cmptag)
77
78 This method checks whether the C<$cmptag> matches the C<$tagname>
79 in the C<$namespace>.
80
81 C<$cmptag> needs to come from the XML::Parser::Expat as it has
82 some magic attached that stores the namespace.
83
84 =cut
85
86 sub nseq {
87 my ($self, $ns, $name, $tag) = @_;
88
89 unless (exists $self->{nso}->{$ns}->{$name}) {
90 $self->{nso}->{$ns}->{$name} =
91 $self->{parser}->generate_ns_name ($name, $ns);
92 }
93
94 return $self->{parser}->eq_name ($self->{nso}->{$ns}->{$name}, $tag);
95 }
96
97 =head2 feed ($data)
98
99 This method feeds a chunk of unparsed data to the parser.
100
101 =cut
102
103 sub feed {
104 my ($self, $data) = @_;
105 $self->{parser}->parse_more ($data);
106 }
107
108
109 sub cb_start_tag {
110 my ($self, $p, $el, %attrs) = @_;
111 push @{$self->{nodestack}}, Net::XMPP2::Node->new ($p->namespace ($el), $el, \%attrs, $self);
112 }
113
114 sub cb_char_data {
115 my ($self, $p, $str) = @_;
116 unless (@{$self->{nodestack}}) {
117 warn "characters outside of tag: [$str]!\n";
118 return;
119 }
120 $self->{nodestack}->[-1]->add_text ($str);
121 }
122
123 sub cb_end_tag {
124 my ($self, $p, $el) = @_;
125
126 unless (@{$self->{nodestack}}) {
127 warn "end tag </$el> read without any starting tag!\n";
128 return;
129 }
130
131 if (!$p->eq_name ($self->{nodestack}->[-1]->name, $el)) {
132 warn "end tag </$el> doesn't match start tags ($self->{tags}->[-1]->[0])!\n";
133 return;
134 }
135
136 my $node = pop @{$self->{nodestack}};
137
138 # > 1 because we don't want the stream tag to save all our children...
139 if (@{$self->{nodestack}} > 1) {
140 $self->{nodestack}->[-1]->add_node ($node);
141 }
142
143 if (@{$self->{nodestack}} == 1) {
144 $self->{stanza_cb}->($self, $node);
145 }
146 }
147
148 =head1 AUTHOR
149
150 Robin Redeker, C<< <elmex at ta-sa.org> >>
151
152 =head1 BUGS
153
154 Please report any bugs or feature requests to
155 C<bug-net-xmpp2 at rt.cpan.org>, or through the web interface at
156 L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Net-XMPP2>.
157 I will be notified, and then you'll automatically be notified of progress on
158 your bug as I make changes.
159
160 =head1 SUPPORT
161
162 You can find documentation for this module with the perldoc command.
163
164 perldoc Net::XMPP2
165
166 You can also look for information at:
167
168 =over 4
169
170 =item * AnnoCPAN: Annotated CPAN documentation
171
172 L<http://annocpan.org/dist/Net-XMPP2>
173
174 =item * CPAN Ratings
175
176 L<http://cpanratings.perl.org/d/Net-XMPP2>
177
178 =item * RT: CPAN's request tracker
179
180 L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Net-XMPP2>
181
182 =item * Search CPAN
183
184 L<http://search.cpan.org/dist/Net-XMPP2>
185
186 =back
187
188 =head1 ACKNOWLEDGEMENTS
189
190 =head1 COPYRIGHT & LICENSE
191
192 Copyright 2007 Robin Redeker, all rights reserved.
193
194 This program is free software; you can redistribute it and/or modify it
195 under the same terms as Perl itself.
196
197 =cut
198
199 1; # End of Net::XMPP2