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