File Coverage

blib/lib/BZ/Client/XMLRPC/Parser.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             #!/bin/false
2             # PODNAME: BZ::Client::XMLRPC::Parser
3             # ABSTRACT: A parser for an XML-RPC response.
4             # vim: softtabstop=4 tabstop=4 shiftwidth=4 ft=perl expandtab smarttab
5              
6 1     1   5 use strict;
  1         3  
  1         24  
7 1     1   4 use warnings 'all';
  1         2  
  1         39  
8              
9             package BZ::Client::XMLRPC::Parser;
10             $BZ::Client::XMLRPC::Parser::VERSION = '4.4002';
11 1     1   319 use BZ::Client::XMLRPC::Response;
  1         4  
  1         29  
12 1     1   5 use BZ::Client::Exception;
  1         3  
  1         14  
13 1     1   247 use XML::Parser ();
  0            
  0            
14              
15             sub new {
16             my $class = shift;
17             return bless({ @_ }, ref($class) || $class);
18             }
19              
20             sub parse {
21             my($self, $content) = @_;
22             $self->{'stack'} = [];
23             my $handler = BZ::Client::XMLRPC::Response->new();
24             $self->register($self, $handler, sub {
25             my($self, $handler) = @_;
26             $self->{'exception'} = $handler->exception();
27             $self->{'result'} = $handler->result();
28             });
29             my $start = sub {
30             my(undef, $name) = @_;
31             my $current = $self->{'current'};
32             $self->error('Illegal state, no more handlers available on stack.') unless $current;
33             $current->start($name);
34             };
35             my $end = sub {
36             my(undef, $name) = @_;
37             my $current = $self->{'current'};
38             $self->error('Illegal state, no more handlers available on stack.') unless $current;
39             $current->end($name);
40             };
41             my $chars = sub {
42             my(undef, $text) = @_;
43             my $current = $self->{'current'};
44             $self->error('Illegal state, no more handlers available on stack.')
45             unless $current;
46             $current->characters($text);
47             };
48             my $parser = XML::Parser->new(
49             Handlers => {
50             Start => $start,
51             End => $end,
52             Char => $chars
53             });
54             $parser->parse($content);
55             die $self->{'exception'}
56             if $self->{'exception'};
57             return $self->{'result'}
58             }
59              
60             sub register {
61             my($self, $parent, $handler, $code) = @_;
62             my $current = [$parent, $handler, $code];
63             if ($parent->can('dec_level')) {
64             $parent->dec_level();
65             }
66             $self->{'current'} = $handler;
67             push @{$self->{'stack'}}, $current;
68             $handler->init($self)
69             }
70              
71             sub remove {
72             my($self, $handler) = @_;
73             my $stack = $self->{'stack'};
74             my $top = pop @$stack;
75             $self->{'current'} = @$stack ? $stack->[@$stack-1]->[1] : undef;
76             $self->error('Illegal state, no more handlers available on stack.') unless $top;
77             my($parent, $h, $code) = @$top;
78             $self->error('Illegal state, the current handler is not the topmost.') unless $h eq $handler;
79             &$code($parent, $h)
80             }
81              
82             sub error {
83             my($self, $message) = @_;
84             BZ::Client::Exception->throw('message' => $message)
85             }
86              
87             sub result {
88             my $self = shift;
89             my $res = $self->{'result'};
90             return $res
91             }
92              
93             sub exception {
94             my $self = shift;
95             return $self->{'exception'}
96             }
97              
98             1;
99              
100             __END__
101              
102             =pod
103              
104             =encoding UTF-8
105              
106             =head1 NAME
107              
108             BZ::Client::XMLRPC::Parser - A parser for an XML-RPC response.
109              
110             =head1 VERSION
111              
112             version 4.4002
113              
114             =head1 AUTHORS
115              
116             =over 4
117              
118             =item *
119              
120             Dean Hamstead <dean@bytefoundry.com.au>
121              
122             =item *
123              
124             Jochen Wiedmann <jochen.wiedmann@gmail.com>
125              
126             =back
127              
128             =head1 COPYRIGHT AND LICENSE
129              
130             This software is copyright (c) 2017 by Dean Hamstad.
131              
132             This is free software; you can redistribute it and/or modify it under
133             the same terms as the Perl 5 programming language system itself.
134              
135             =cut