1package DJabberd::TestSAXHandler; 2use strict; 3use base qw(XML::SAX::Base); 4use DJabberd::SAXHandler; 5use DJabberd::XMLElement; 6use DJabberd::StreamStart; 7 8sub new { 9 my ($class, $listref) = @_; 10 my $self = $class->SUPER::new; 11 $self->{"listref"} = $listref; 12 $self->{"capture_depth"} = 0; # on transition from 1 to 0, stop capturing 13 $self->{"on_end_capture"} = undef; # undef or $subref->($doc) 14 $self->{"events"} = []; # capturing events 15 return $self; 16} 17 18use constant EVT_START_ELEMENT => 1; 19use constant EVT_END_ELEMENT => 2; 20use constant EVT_CHARS => 3; 21 22sub start_element { 23 my $self = shift; 24 my $data = shift; 25 26 if ($self->{capture_depth}) { 27 push @{$self->{events}}, [EVT_START_ELEMENT, $data]; 28 $self->{capture_depth}++; 29 return; 30 } 31 32 if ($data->{LocalName} eq "djab-noop") { 33 return; 34 } 35 36 # {=xml-stream} 37 if ($data->{NamespaceURI} eq "http://etherx.jabber.org/streams" && 38 $data->{LocalName} eq "stream") { 39 40 my $ss = DJabberd::StreamStart->new($data); 41 push @{$self->{listref}}, $ss; 42 return; 43 } 44 45 my $start_capturing = sub { 46 my $cb = shift; 47 48 $self->{"events"} = []; # capturing events 49 $self->{capture_depth} = 1; 50 51 # capture via saving SAX events 52 push @{$self->{events}}, [EVT_START_ELEMENT, $data]; 53 54 $self->{on_end_capture} = $cb; 55 return 1; 56 }; 57 58 return $start_capturing->(sub { 59 my ($doc, $events) = @_; 60 my $nodes = _nodes_from_events($events); 61 # {=xml-stanza} 62 push @{$self->{listref}}, $nodes->[0]; 63 }); 64 65} 66 67sub characters { 68 my ($self, $data) = @_; 69 70 if ($self->{capture_depth}) { 71 push @{$self->{events}}, [EVT_CHARS, $data]; 72 } 73} 74 75sub end_element { 76 my ($self, $data) = @_; 77 78 if ($data->{NamespaceURI} eq "http://etherx.jabber.org/streams" && 79 $data->{LocalName} eq "stream") { 80 push @{$self->{listref}}, "end-stream"; 81 return; 82 } 83 84 if ($self->{capture_depth}) { 85 push @{$self->{events}}, [EVT_END_ELEMENT, $data]; 86 $self->{capture_depth}--; 87 return if $self->{capture_depth}; 88 my $doc = undef; 89 if (my $cb = $self->{on_end_capture}) { 90 $cb->($doc, $self->{events}); 91 } 92 return; 93 } 94} 95 96*_nodes_from_events = \&DJabberd::SAXHandler::_nodes_from_events; 97 981; 99