Filename | /usr/lib/perl5/XML/LibXSLT.pm |
Statements | Executed 1312 statements in 64.8ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 10.1ms | 10.1ms | _parse_stylesheet (xsub) | XML::LibXSLT::
25 | 1 | 1 | 1.12ms | 2.01ms | _init_callbacks | XML::LibXSLT::StylesheetWrapper::
25 | 1 | 1 | 915µs | 47.5ms | transform | XML::LibXSLT::StylesheetWrapper::
25 | 1 | 1 | 467µs | 924µs | _cleanup_callbacks | XML::LibXSLT::StylesheetWrapper::
50 | 2 | 1 | 278µs | 278µs | match_callback | XML::LibXSLT::StylesheetWrapper::
1 | 1 | 1 | 261µs | 261µs | bootstrap (xsub) | XML::LibXSLT::
25 | 1 | 1 | 248µs | 1.79ms | output_string | XML::LibXSLT::StylesheetWrapper::
25 | 1 | 1 | 152µs | 152µs | read_callback | XML::LibXSLT::StylesheetWrapper::
25 | 1 | 1 | 151µs | 151µs | open_callback | XML::LibXSLT::StylesheetWrapper::
25 | 1 | 1 | 127µs | 127µs | close_callback | XML::LibXSLT::StylesheetWrapper::
26 | 2 | 1 | 112µs | 112µs | lib_init_callbacks (xsub) | XML::LibXSLT::
1 | 1 | 1 | 101µs | 909µs | BEGIN@23 | XML::LibXSLT::
1 | 1 | 1 | 63µs | 10.3ms | parse_stylesheet | XML::LibXSLT::
1 | 1 | 1 | 61µs | 120µs | _init_callbacks | XML::LibXSLT::
1 | 1 | 1 | 36µs | 47µs | BEGIN@11 | XML::LibXSLT::
1 | 1 | 1 | 34µs | 152µs | BEGIN@310 | XML::LibXSLT::StylesheetWrapper::
1 | 1 | 1 | 27µs | 27µs | new | XML::LibXSLT::
1 | 1 | 1 | 26µs | 34µs | BEGIN@503 | XML::LibXSLT::Security::
1 | 1 | 1 | 26µs | 498µs | BEGIN@16 | XML::LibXSLT::
1 | 1 | 1 | 23µs | 29µs | BEGIN@17 | XML::LibXSLT::
1 | 1 | 1 | 23µs | 113µs | BEGIN@313 | XML::LibXSLT::StylesheetWrapper::
1 | 1 | 1 | 23µs | 102µs | BEGIN@24 | XML::LibXSLT::
1 | 1 | 1 | 22µs | 26µs | BEGIN@20 | XML::LibXSLT::
1 | 1 | 1 | 22µs | 25µs | BEGIN@18 | XML::LibXSLT::
1 | 1 | 1 | 21µs | 57µs | BEGIN@79 | XML::LibXSLT::
1 | 1 | 1 | 21µs | 27µs | BEGIN@309 | XML::LibXSLT::StylesheetWrapper::
1 | 1 | 1 | 21µs | 24µs | BEGIN@19 | XML::LibXSLT::
1 | 1 | 1 | 21µs | 112µs | BEGIN@504 | XML::LibXSLT::Security::
1 | 1 | 1 | 18µs | 219µs | BEGIN@12 | XML::LibXSLT::
1 | 1 | 1 | 18µs | 99µs | BEGIN@506 | XML::LibXSLT::Security::
1 | 1 | 1 | 18µs | 466µs | BEGIN@312 | XML::LibXSLT::StylesheetWrapper::
1 | 1 | 1 | 16µs | 37µs | _cleanup_callbacks | XML::LibXSLT::
2 | 2 | 1 | 12µs | 12µs | match_callback | XML::LibXSLT::
1 | 1 | 1 | 5µs | 5µs | read_callback | XML::LibXSLT::
1 | 1 | 1 | 5µs | 5µs | open_callback | XML::LibXSLT::
1 | 1 | 1 | 4µs | 4µs | close_callback | XML::LibXSLT::
1 | 1 | 1 | 3µs | 3µs | REQUIRE_XML_LIBXML_ABI_VERSION | XML::LibXSLT::
0 | 0 | 0 | 0s | 0s | _security_check | XML::LibXSLT::Security::
0 | 0 | 0 | 0s | 0s | cleanup_callbacks | XML::LibXSLT::Security::
0 | 0 | 0 | 0s | 0s | init_callbacks | XML::LibXSLT::Security::
0 | 0 | 0 | 0s | 0s | new | XML::LibXSLT::Security::
0 | 0 | 0 | 0s | 0s | register_callback | XML::LibXSLT::Security::
0 | 0 | 0 | 0s | 0s | unregister_callback | XML::LibXSLT::Security::
0 | 0 | 0 | 0s | 0s | callbacks | XML::LibXSLT::StylesheetWrapper::
0 | 0 | 0 | 0s | 0s | input_callbacks | XML::LibXSLT::StylesheetWrapper::
0 | 0 | 0 | 0s | 0s | media_type | XML::LibXSLT::StylesheetWrapper::
0 | 0 | 0 | 0s | 0s | output_as_bytes | XML::LibXSLT::StylesheetWrapper::
0 | 0 | 0 | 0s | 0s | output_as_chars | XML::LibXSLT::StylesheetWrapper::
0 | 0 | 0 | 0s | 0s | output_encoding | XML::LibXSLT::StylesheetWrapper::
0 | 0 | 0 | 0s | 0s | output_fh | XML::LibXSLT::StylesheetWrapper::
0 | 0 | 0 | 0s | 0s | output_file | XML::LibXSLT::StylesheetWrapper::
0 | 0 | 0 | 0s | 0s | security_callbacks | XML::LibXSLT::StylesheetWrapper::
0 | 0 | 0 | 0s | 0s | transform_file | XML::LibXSLT::StylesheetWrapper::
0 | 0 | 0 | 0s | 0s | callbacks | XML::LibXSLT::
0 | 0 | 0 | 0s | 0s | input_callbacks | XML::LibXSLT::
0 | 0 | 0 | 0s | 0s | parse_stylesheet_file | XML::LibXSLT::
0 | 0 | 0 | 0s | 0s | perl_dispatcher | XML::LibXSLT::
0 | 0 | 0 | 0s | 0s | register_xslt_module | XML::LibXSLT::
0 | 0 | 0 | 0s | 0s | security_callbacks | XML::LibXSLT::
0 | 0 | 0 | 0s | 0s | xpath_to_string | XML::LibXSLT::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | # $Id: LibXSLT.pm 228 2009-10-07 12:25:23Z pajas $ | ||||
2 | # | ||||
3 | # This is free software, you may use it and distribute it under the same terms as | ||||
4 | # Perl itself. | ||||
5 | # | ||||
6 | # Copyright 2001-2009 AxKit.com Ltd. | ||||
7 | # | ||||
8 | # | ||||
9 | package XML::LibXSLT; | ||||
10 | |||||
11 | 3 | 82µs | 2 | 58µs | # spent 47µs (36+11) within XML::LibXSLT::BEGIN@11 which was called:
# once (36µs+11µs) by C4::XSLT::BEGIN@35 at line 11 # spent 47µs making 1 call to XML::LibXSLT::BEGIN@11
# spent 11µs making 1 call to strict::import |
12 | 3 | 108µs | 2 | 421µs | # spent 219µs (18+201) within XML::LibXSLT::BEGIN@12 which was called:
# once (18µs+201µs) by C4::XSLT::BEGIN@35 at line 12 # spent 219µs making 1 call to XML::LibXSLT::BEGIN@12
# spent 201µs making 1 call to vars::import |
13 | |||||
14 | 1 | 7µs | # spent 3µs within XML::LibXSLT::REQUIRE_XML_LIBXML_ABI_VERSION which was called:
# once (3µs+0s) by XML::LibXML::VERSION at line 41 of XML/LibXML.pm | ||
15 | |||||
16 | 3 | 63µs | 3 | 971µs | # spent 498µs (26+473) within XML::LibXSLT::BEGIN@16 which was called:
# once (26µs+473µs) by C4::XSLT::BEGIN@35 at line 16 # spent 498µs making 1 call to XML::LibXSLT::BEGIN@16
# spent 380µs making 1 call to XML::LibXML::import
# spent 92µs making 1 call to XML::LibXML::VERSION |
17 | 3 | 52µs | 2 | 36µs | # spent 29µs (23+6) within XML::LibXSLT::BEGIN@17 which was called:
# once (23µs+6µs) by C4::XSLT::BEGIN@35 at line 17 # spent 29µs making 1 call to XML::LibXSLT::BEGIN@17
# spent 6µs making 1 call to UNIVERSAL::import |
18 | 3 | 50µs | 2 | 28µs | # spent 25µs (22+3) within XML::LibXSLT::BEGIN@18 which was called:
# once (22µs+3µs) by C4::XSLT::BEGIN@35 at line 18 # spent 25µs making 1 call to XML::LibXSLT::BEGIN@18
# spent 3µs making 1 call to UNIVERSAL::import |
19 | 3 | 50µs | 2 | 27µs | # spent 24µs (21+3) within XML::LibXSLT::BEGIN@19 which was called:
# once (21µs+3µs) by C4::XSLT::BEGIN@35 at line 19 # spent 24µs making 1 call to XML::LibXSLT::BEGIN@19
# spent 3µs making 1 call to UNIVERSAL::import |
20 | 3 | 68µs | 2 | 29µs | # spent 26µs (22+3) within XML::LibXSLT::BEGIN@20 which was called:
# once (22µs+3µs) by C4::XSLT::BEGIN@35 at line 20 # spent 26µs making 1 call to XML::LibXSLT::BEGIN@20
# spent 3µs making 1 call to UNIVERSAL::import |
21 | |||||
22 | |||||
23 | # spent 909µs (101+808) within XML::LibXSLT::BEGIN@23 which was called:
# once (101µs+808µs) by C4::XSLT::BEGIN@35 at line 44 | ||||
24 | 3 | 215µs | 2 | 181µs | # spent 102µs (23+79) within XML::LibXSLT::BEGIN@24 which was called:
# once (23µs+79µs) by C4::XSLT::BEGIN@35 at line 24 # spent 102µs making 1 call to XML::LibXSLT::BEGIN@24
# spent 79µs making 1 call to Exporter::import |
25 | |||||
26 | 8 | 41µs | require Exporter; | ||
27 | |||||
28 | $VERSION = "1.70"; | ||||
29 | |||||
30 | require DynaLoader; | ||||
31 | |||||
32 | @ISA = qw(DynaLoader); | ||||
33 | |||||
34 | # avoid possible shared library name conflict on Win32 | ||||
35 | # not using this trick on 5.10.0 (suffering from DynaLoader bug) | ||||
36 | local $DynaLoader::dl_dlext = "xs.$DynaLoader::dl_dlext" if (($^O eq 'MSWin32') && ($] ne '5.010000')); | ||||
37 | |||||
38 | 1 | 803µs | bootstrap XML::LibXSLT $VERSION; # spent 803µs making 1 call to DynaLoader::bootstrap | ||
39 | |||||
40 | # the following magic lets XML::LibXSLT internals know | ||||
41 | # where to register XML::LibXML proxy nodes | ||||
42 | 1 | 6µs | INIT_THREAD_SUPPORT() if XML::LibXML::threads_shared_enabled(); # spent 6µs making 1 call to XML::LibXML::threads_shared_enabled | ||
43 | $USE_LIBXML_DATA_TYPES = 0; | ||||
44 | 1 | 364µs | 1 | 909µs | } # spent 909µs making 1 call to XML::LibXSLT::BEGIN@23 |
45 | |||||
46 | |||||
47 | # spent 27µs within XML::LibXSLT::new which was called:
# once (27µs+0s) by C4::XSLT::XSLTParse4Display at line 229 of /usr/share/koha/lib/C4/XSLT.pm | ||||
48 | 4 | 31µs | my $class = shift; | ||
49 | my %options = @_; | ||||
50 | my $self = bless \%options, $class; | ||||
51 | return $self; | ||||
52 | } | ||||
53 | |||||
54 | # ido - perl dispatcher | ||||
55 | sub perl_dispatcher { | ||||
56 | my $func = shift; | ||||
57 | my @params = @_; | ||||
58 | my @perlParams; | ||||
59 | |||||
60 | my $i = 0; | ||||
61 | while (@params) { | ||||
62 | my $type = shift(@params); | ||||
63 | if ($type eq 'XML::LibXML::Literal' or | ||||
64 | $type eq 'XML::LibXML::Number' or | ||||
65 | $type eq 'XML::LibXML::Boolean') | ||||
66 | { | ||||
67 | my $val = shift(@params); | ||||
68 | unshift(@perlParams, $USE_LIBXML_DATA_TYPES ? $type->new($val) : $val); | ||||
69 | } | ||||
70 | elsif ($type eq 'XML::LibXML::NodeList') { | ||||
71 | my $node_count = shift(@params); | ||||
72 | my @nodes = splice(@params, 0, $node_count); | ||||
73 | # warn($_->getName) for @nodes; | ||||
74 | unshift(@perlParams, $type->new(@nodes)); | ||||
75 | } | ||||
76 | } | ||||
77 | |||||
78 | $func = "main::$func" unless ref($func) || $func =~ /(.+)::/; | ||||
79 | 3 | 1.75ms | 2 | 93µs | # spent 57µs (21+36) within XML::LibXSLT::BEGIN@79 which was called:
# once (21µs+36µs) by C4::XSLT::BEGIN@35 at line 79 # spent 57µs making 1 call to XML::LibXSLT::BEGIN@79
# spent 36µs making 1 call to strict::unimport |
80 | my $res = $func->(@perlParams); | ||||
81 | return $res; | ||||
82 | } | ||||
83 | |||||
84 | |||||
85 | sub xpath_to_string { | ||||
86 | my @results; | ||||
87 | while (@_) { | ||||
88 | my $value = shift(@_); $value = '' unless defined $value; | ||||
89 | push @results, $value; | ||||
90 | if (@results % 2) { | ||||
91 | # key | ||||
92 | $results[-1] =~ s/:/_/g; # XSLT doesn't like names with colons | ||||
93 | } | ||||
94 | else { | ||||
95 | if ($value =~ s/'/', "'", '/g) { | ||||
96 | $results[-1] = "concat('$value')"; | ||||
97 | } | ||||
98 | else { | ||||
99 | $results[-1] = "'$results[-1]'"; | ||||
100 | } | ||||
101 | } | ||||
102 | } | ||||
103 | return @results; | ||||
104 | } | ||||
105 | |||||
106 | #-------------------------------------------------------------------------# | ||||
107 | # callback functions # | ||||
108 | #-------------------------------------------------------------------------# | ||||
109 | |||||
110 | sub security_callbacks { | ||||
111 | my $self = shift; | ||||
112 | my $scbclass = shift; | ||||
113 | |||||
114 | if ( defined $scbclass ) { | ||||
115 | $self->{XML_LIBXSLT_SECPREFS} = $scbclass; | ||||
116 | } | ||||
117 | return $self->{XML_LIBXSLT_SECPREFS}; | ||||
118 | } | ||||
119 | |||||
120 | sub input_callbacks { | ||||
121 | my $self = shift; | ||||
122 | my $icbclass = shift; | ||||
123 | |||||
124 | if ( defined $icbclass ) { | ||||
125 | $self->{XML_LIBXSLT_CALLBACK_STACK} = $icbclass; | ||||
126 | } | ||||
127 | return $self->{XML_LIBXSLT_CALLBACK_STACK}; | ||||
128 | } | ||||
129 | |||||
130 | sub match_callback { | ||||
131 | 8 | 15µs | my $self = shift; | ||
132 | if ( ref $self ) { | ||||
133 | if ( scalar @_ ) { | ||||
134 | $self->{XML_LIBXSLT_MATCH_CB} = shift; | ||||
135 | $self->{XML_LIBXSLT_CALLBACK_STACK} = undef; | ||||
136 | } | ||||
137 | return $self->{XML_LIBXSLT_MATCH_CB}; | ||||
138 | } | ||||
139 | else { | ||||
140 | $MatchCB = shift if scalar @_; | ||||
141 | return $MatchCB; | ||||
142 | } | ||||
143 | } | ||||
144 | |||||
145 | # spent 5µs within XML::LibXSLT::read_callback which was called:
# once (5µs+0s) by XML::LibXSLT::_init_callbacks at line 223 | ||||
146 | 4 | 7µs | my $self = shift; | ||
147 | if ( ref $self ) { | ||||
148 | if ( scalar @_ ) { | ||||
149 | $self->{XML_LIBXSLT_READ_CB} = shift; | ||||
150 | $self->{XML_LIBXSLT_CALLBACK_STACK} = undef; | ||||
151 | } | ||||
152 | return $self->{XML_LIBXSLT_READ_CB}; | ||||
153 | } | ||||
154 | else { | ||||
155 | $ReadCB = shift if scalar @_; | ||||
156 | return $ReadCB; | ||||
157 | } | ||||
158 | } | ||||
159 | |||||
160 | # spent 4µs within XML::LibXSLT::close_callback which was called:
# once (4µs+0s) by XML::LibXSLT::_init_callbacks at line 224 | ||||
161 | 4 | 9µs | my $self = shift; | ||
162 | if ( ref $self ) { | ||||
163 | if ( scalar @_ ) { | ||||
164 | $self->{XML_LIBXSLT_CLOSE_CB} = shift; | ||||
165 | $self->{XML_LIBXSLT_CALLBACK_STACK} = undef; | ||||
166 | } | ||||
167 | return $self->{XML_LIBXSLT_CLOSE_CB}; | ||||
168 | } | ||||
169 | else { | ||||
170 | $CloseCB = shift if scalar @_; | ||||
171 | return $CloseCB; | ||||
172 | } | ||||
173 | } | ||||
174 | |||||
175 | # spent 5µs within XML::LibXSLT::open_callback which was called:
# once (5µs+0s) by XML::LibXSLT::_init_callbacks at line 222 | ||||
176 | 4 | 8µs | my $self = shift; | ||
177 | if ( ref $self ) { | ||||
178 | if ( scalar @_ ) { | ||||
179 | $self->{XML_LIBXSLT_OPEN_CB} = shift; | ||||
180 | $self->{XML_LIBXSLT_CALLBACK_STACK} = undef; | ||||
181 | } | ||||
182 | return $self->{XML_LIBXSLT_OPEN_CB}; | ||||
183 | } | ||||
184 | else { | ||||
185 | $OpenCB = shift if scalar @_; | ||||
186 | return $OpenCB; | ||||
187 | } | ||||
188 | } | ||||
189 | |||||
190 | sub callbacks { | ||||
191 | my $self = shift; | ||||
192 | if ( ref $self ) { | ||||
193 | if (@_) { | ||||
194 | my ($match, $open, $read, $close) = @_; | ||||
195 | @{$self}{qw(XML_LIBXSLT_MATCH_CB XML_LIBXSLT_OPEN_CB XML_LIBXSLT_READ_CB XML_LIBXSLT_CLOSE_CB)} = ($match, $open, $read, $close); | ||||
196 | $self->{XML_LIBXSLT_CALLBACK_STACK} = undef; | ||||
197 | } | ||||
198 | else { | ||||
199 | return @{$self}{qw(XML_LIBXSLT_MATCH_CB XML_LIBXSLT_OPEN_CB XML_LIBXSLT_READ_CB XML_LIBXSLT_CLOSE_CB)}; | ||||
200 | } | ||||
201 | } | ||||
202 | else { | ||||
203 | if (@_) { | ||||
204 | ( $MatchCB, $OpenCB, $ReadCB, $CloseCB ) = @_; | ||||
205 | } | ||||
206 | else { | ||||
207 | return ( $MatchCB, $OpenCB, $ReadCB, $CloseCB ); | ||||
208 | } | ||||
209 | } | ||||
210 | } | ||||
211 | |||||
212 | # spent 120µs (61+60) within XML::LibXSLT::_init_callbacks which was called:
# once (61µs+60µs) by XML::LibXSLT::parse_stylesheet at line 246 | ||||
213 | 12 | 67µs | my $self = shift; | ||
214 | my $icb = $self->{XML_LIBXSLT_CALLBACK_STACK}; | ||||
215 | |||||
216 | unless ( defined $icb ) { | ||||
217 | 1 | 5µs | $self->{XML_LIBXSLT_CALLBACK_STACK} = XML::LibXML::InputCallback->new(); # spent 5µs making 1 call to XML::LibXML::InputCallback::new | ||
218 | $icb = $self->{XML_LIBXSLT_CALLBACK_STACK}; | ||||
219 | } | ||||
220 | |||||
221 | 1 | 5µs | my $mcb = $self->match_callback(); # spent 5µs making 1 call to XML::LibXSLT::match_callback | ||
222 | 1 | 5µs | my $ocb = $self->open_callback(); # spent 5µs making 1 call to XML::LibXSLT::open_callback | ||
223 | 1 | 5µs | my $rcb = $self->read_callback(); # spent 5µs making 1 call to XML::LibXSLT::read_callback | ||
224 | 1 | 4µs | my $ccb = $self->close_callback(); # spent 4µs making 1 call to XML::LibXSLT::close_callback | ||
225 | |||||
226 | if ( defined $mcb and defined $ocb and defined $rcb and defined $ccb ) { | ||||
227 | $icb->register_callbacks( [$mcb, $ocb, $rcb, $ccb] ); | ||||
228 | } | ||||
229 | |||||
230 | 1 | 20µs | $self->lib_init_callbacks(); # spent 20µs making 1 call to XML::LibXSLT::lib_init_callbacks | ||
231 | 1 | 16µs | $icb->init_callbacks(); # spent 16µs making 1 call to XML::LibXML::InputCallback::init_callbacks | ||
232 | } | ||||
233 | |||||
234 | # spent 37µs (16+21) within XML::LibXSLT::_cleanup_callbacks which was called:
# once (16µs+21µs) by XML::LibXSLT::parse_stylesheet at line 251 | ||||
235 | 4 | 14µs | my $self = shift; | ||
236 | 1 | 14µs | $self->{XML_LIBXSLT_CALLBACK_STACK}->cleanup_callbacks(); # spent 14µs making 1 call to XML::LibXML::InputCallback::cleanup_callbacks | ||
237 | 1 | 7µs | my $mcb = $self->match_callback(); # spent 7µs making 1 call to XML::LibXSLT::match_callback | ||
238 | if ( defined $mcb ) { | ||||
239 | $self->{XML_LIBXSLT_CALLBACK_STACK}->unregister_callbacks( [$mcb] ); | ||||
240 | } | ||||
241 | } | ||||
242 | |||||
243 | # spent 10.3ms (63µs+10.3) within XML::LibXSLT::parse_stylesheet which was called:
# once (63µs+10.3ms) by C4::XSLT::XSLTParse4Display at line 238 of /usr/share/koha/lib/C4/XSLT.pm | ||||
244 | 10 | 8.44ms | my $self = shift; | ||
245 | |||||
246 | 1 | 120µs | $self->_init_callbacks(); # spent 120µs making 1 call to XML::LibXSLT::_init_callbacks | ||
247 | |||||
248 | my $stylesheet; | ||||
249 | 1 | 1.70ms | 3 | 10.1ms | eval { $stylesheet = $self->_parse_stylesheet(@_); }; # spent 10.1ms making 1 call to XML::LibXSLT::_parse_stylesheet
# spent 26µs making 2 calls to XML::LibXML::InputCallback::_callback_match, avg 13µs/call |
250 | |||||
251 | 1 | 37µs | $self->_cleanup_callbacks(); # spent 37µs making 1 call to XML::LibXSLT::_cleanup_callbacks | ||
252 | |||||
253 | my $err = $@; | ||||
254 | if ($err) { | ||||
255 | croak $err; | ||||
256 | } | ||||
257 | |||||
258 | my $rv = { | ||||
259 | XML_LIBXSLT_STYLESHEET => $stylesheet, | ||||
260 | XML_LIBXSLT_CALLBACK_STACK => $self->{XML_LIBXSLT_CALLBACK_STACK}, | ||||
261 | XML_LIBXSLT_MATCH_CB => $self->{XML_LIBXSLT_MATCH_CB}, | ||||
262 | XML_LIBXSLT_OPEN_CB => $self->{XML_LIBXSLT_OPEN_CB}, | ||||
263 | XML_LIBXSLT_READ_CB => $self->{XML_LIBXSLT_READ_CB}, | ||||
264 | XML_LIBXSLT_CLOSE_CB => $self->{XML_LIBXSLT_CLOSE_CB}, | ||||
265 | XML_LIBXSLT_SECPREFS => $self->{XML_LIBXSLT_SECPREFS}, | ||||
266 | }; | ||||
267 | |||||
268 | return bless $rv, "XML::LibXSLT::StylesheetWrapper"; | ||||
269 | } | ||||
270 | |||||
271 | sub parse_stylesheet_file { | ||||
272 | my $self = shift; | ||||
273 | |||||
274 | $self->_init_callbacks(); | ||||
275 | |||||
276 | my $stylesheet; | ||||
277 | eval { $stylesheet = $self->_parse_stylesheet_file(@_); }; | ||||
278 | |||||
279 | $self->_cleanup_callbacks(); | ||||
280 | |||||
281 | my $err = $@; | ||||
282 | if ($err) { | ||||
283 | croak $err; | ||||
284 | } | ||||
285 | |||||
286 | my $rv = { | ||||
287 | XML_LIBXSLT_STYLESHEET => $stylesheet, | ||||
288 | XML_LIBXSLT_CALLBACK_STACK => $self->{XML_LIBXSLT_CALLBACK_STACK}, | ||||
289 | XML_LIBXSLT_MATCH_CB => $self->{XML_LIBXSLT_MATCH_CB}, | ||||
290 | XML_LIBXSLT_OPEN_CB => $self->{XML_LIBXSLT_OPEN_CB}, | ||||
291 | XML_LIBXSLT_READ_CB => $self->{XML_LIBXSLT_READ_CB}, | ||||
292 | XML_LIBXSLT_CLOSE_CB => $self->{XML_LIBXSLT_CLOSE_CB}, | ||||
293 | XML_LIBXSLT_SECPREFS => $self->{XML_LIBXSLT_SECPREFS}, | ||||
294 | }; | ||||
295 | |||||
296 | return bless $rv, "XML::LibXSLT::StylesheetWrapper"; | ||||
297 | } | ||||
298 | |||||
299 | sub register_xslt_module { | ||||
300 | my $self = shift; | ||||
301 | my $module = shift; | ||||
302 | # Not implemented | ||||
303 | } | ||||
304 | |||||
305 | 1 | 300ns | 1; | ||
306 | |||||
307 | package XML::LibXSLT::StylesheetWrapper; | ||||
308 | |||||
309 | 3 | 53µs | 2 | 34µs | # spent 27µs (21+6) within XML::LibXSLT::StylesheetWrapper::BEGIN@309 which was called:
# once (21µs+6µs) by C4::XSLT::BEGIN@35 at line 309 # spent 27µs making 1 call to XML::LibXSLT::StylesheetWrapper::BEGIN@309
# spent 6µs making 1 call to strict::import |
310 | 3 | 83µs | 2 | 270µs | # spent 152µs (34+118) within XML::LibXSLT::StylesheetWrapper::BEGIN@310 which was called:
# once (34µs+118µs) by C4::XSLT::BEGIN@35 at line 310 # spent 152µs making 1 call to XML::LibXSLT::StylesheetWrapper::BEGIN@310
# spent 118µs making 1 call to vars::import |
311 | |||||
312 | 3 | 62µs | 2 | 914µs | # spent 466µs (18+448) within XML::LibXSLT::StylesheetWrapper::BEGIN@312 which was called:
# once (18µs+448µs) by C4::XSLT::BEGIN@35 at line 312 # spent 466µs making 1 call to XML::LibXSLT::StylesheetWrapper::BEGIN@312
# spent 448µs making 1 call to XML::LibXML::import |
313 | 3 | 1.95ms | 2 | 203µs | # spent 113µs (23+90) within XML::LibXSLT::StylesheetWrapper::BEGIN@313 which was called:
# once (23µs+90µs) by C4::XSLT::BEGIN@35 at line 313 # spent 113µs making 1 call to XML::LibXSLT::StylesheetWrapper::BEGIN@313
# spent 90µs making 1 call to Exporter::import |
314 | |||||
315 | sub security_callbacks { | ||||
316 | my $self = shift; | ||||
317 | my $scbclass = shift; | ||||
318 | |||||
319 | if ( defined $scbclass ) { | ||||
320 | $self->{XML_LIBXSLT_SECPREFS} = $scbclass; | ||||
321 | } | ||||
322 | return $self->{XML_LIBXSLT_SECPREFS}; | ||||
323 | } | ||||
324 | |||||
325 | sub input_callbacks { | ||||
326 | my $self = shift; | ||||
327 | my $icbclass = shift; | ||||
328 | |||||
329 | if ( defined $icbclass ) { | ||||
330 | $self->{XML_LIBXSLT_CALLBACK_STACK} = $icbclass; | ||||
331 | } | ||||
332 | return $self->{XML_LIBXSLT_CALLBACK_STACK}; | ||||
333 | } | ||||
334 | |||||
335 | # spent 278µs within XML::LibXSLT::StylesheetWrapper::match_callback which was called 50 times, avg 6µs/call:
# 25 times (139µs+0s) by XML::LibXSLT::StylesheetWrapper::_init_callbacks at line 426, avg 6µs/call
# 25 times (138µs+0s) by XML::LibXSLT::StylesheetWrapper::_cleanup_callbacks at line 446, avg 6µs/call | ||||
336 | 200 | 366µs | my $self = shift; | ||
337 | if ( ref $self ) { | ||||
338 | if ( scalar @_ ) { | ||||
339 | $self->{XML_LIBXSLT_MATCH_CB} = shift; | ||||
340 | $self->{XML_LIBXSLT_CALLBACK_STACK} = undef; | ||||
341 | } | ||||
342 | return $self->{XML_LIBXSLT_MATCH_CB}; | ||||
343 | } | ||||
344 | else { | ||||
345 | $MatchCB = shift if scalar @_; | ||||
346 | return $MatchCB; | ||||
347 | } | ||||
348 | } | ||||
349 | |||||
350 | # spent 152µs within XML::LibXSLT::StylesheetWrapper::read_callback which was called 25 times, avg 6µs/call:
# 25 times (152µs+0s) by XML::LibXSLT::StylesheetWrapper::_init_callbacks at line 428, avg 6µs/call | ||||
351 | 100 | 221µs | my $self = shift; | ||
352 | if ( ref $self ) { | ||||
353 | if ( scalar @_ ) { | ||||
354 | $self->{XML_LIBXSLT_READ_CB} = shift; | ||||
355 | $self->{XML_LIBXSLT_CALLBACK_STACK} = undef; | ||||
356 | } | ||||
357 | return $self->{XML_LIBXSLT_READ_CB}; | ||||
358 | } | ||||
359 | else { | ||||
360 | $ReadCB = shift if scalar @_; | ||||
361 | return $ReadCB; | ||||
362 | } | ||||
363 | } | ||||
364 | |||||
365 | # spent 127µs within XML::LibXSLT::StylesheetWrapper::close_callback which was called 25 times, avg 5µs/call:
# 25 times (127µs+0s) by XML::LibXSLT::StylesheetWrapper::_init_callbacks at line 429, avg 5µs/call | ||||
366 | 100 | 159µs | my $self = shift; | ||
367 | if ( ref $self ) { | ||||
368 | if ( scalar @_ ) { | ||||
369 | $self->{XML_LIBXSLT_CLOSE_CB} = shift; | ||||
370 | $self->{XML_LIBXSLT_CALLBACK_STACK} = undef; | ||||
371 | } | ||||
372 | return $self->{XML_LIBXSLT_CLOSE_CB}; | ||||
373 | } | ||||
374 | else { | ||||
375 | $CloseCB = shift if scalar @_; | ||||
376 | return $CloseCB; | ||||
377 | } | ||||
378 | } | ||||
379 | |||||
380 | # spent 151µs within XML::LibXSLT::StylesheetWrapper::open_callback which was called 25 times, avg 6µs/call:
# 25 times (151µs+0s) by XML::LibXSLT::StylesheetWrapper::_init_callbacks at line 427, avg 6µs/call | ||||
381 | 100 | 188µs | my $self = shift; | ||
382 | if ( ref $self ) { | ||||
383 | if ( scalar @_ ) { | ||||
384 | $self->{XML_LIBXSLT_OPEN_CB} = shift; | ||||
385 | $self->{XML_LIBXSLT_CALLBACK_STACK} = undef; | ||||
386 | } | ||||
387 | return $self->{XML_LIBXSLT_OPEN_CB}; | ||||
388 | } | ||||
389 | else { | ||||
390 | $OpenCB = shift if scalar @_; | ||||
391 | return $OpenCB; | ||||
392 | } | ||||
393 | } | ||||
394 | |||||
395 | sub callbacks { | ||||
396 | my $self = shift; | ||||
397 | if ( ref $self ) { | ||||
398 | if (@_) { | ||||
399 | my ($match, $open, $read, $close) = @_; | ||||
400 | @{$self}{qw(XML_LIBXSLT_MATCH_CB XML_LIBXSLT_OPEN_CB XML_LIBXSLT_READ_CB XML_LIBXSLT_CLOSE_CB)} = ($match, $open, $read, $close); | ||||
401 | $self->{XML_LIBXSLT_CALLBACK_STACK} = undef; | ||||
402 | } | ||||
403 | else { | ||||
404 | return @{$self}{qw(XML_LIBXSLT_MATCH_CB XML_LIBXSLT_OPEN_CB XML_LIBXSLT_READ_CB XML_LIBXSLT_CLOSE_CB)}; | ||||
405 | } | ||||
406 | } | ||||
407 | else { | ||||
408 | if (@_) { | ||||
409 | ( $MatchCB, $OpenCB, $ReadCB, $CloseCB ) = @_; | ||||
410 | } | ||||
411 | else { | ||||
412 | return ( $MatchCB, $OpenCB, $ReadCB, $CloseCB ); | ||||
413 | } | ||||
414 | } | ||||
415 | } | ||||
416 | |||||
417 | # spent 2.01ms (1.12+894µs) within XML::LibXSLT::StylesheetWrapper::_init_callbacks which was called 25 times, avg 80µs/call:
# 25 times (1.12ms+894µs) by XML::LibXSLT::StylesheetWrapper::transform at line 461, avg 80µs/call | ||||
418 | 300 | 1.02ms | my $self = shift; | ||
419 | my $icb = $self->{XML_LIBXSLT_CALLBACK_STACK}; | ||||
420 | |||||
421 | unless ( defined $icb ) { | ||||
422 | $self->{XML_LIBXSLT_CALLBACK_STACK} = XML::LibXML::InputCallback->new(); | ||||
423 | $icb = $self->{XML_LIBXSLT_CALLBACK_STACK}; | ||||
424 | } | ||||
425 | |||||
426 | 25 | 139µs | my $mcb = $self->match_callback(); # spent 139µs making 25 calls to XML::LibXSLT::StylesheetWrapper::match_callback, avg 6µs/call | ||
427 | 25 | 151µs | my $ocb = $self->open_callback(); # spent 151µs making 25 calls to XML::LibXSLT::StylesheetWrapper::open_callback, avg 6µs/call | ||
428 | 25 | 152µs | my $rcb = $self->read_callback(); # spent 152µs making 25 calls to XML::LibXSLT::StylesheetWrapper::read_callback, avg 6µs/call | ||
429 | 25 | 127µs | my $ccb = $self->close_callback(); # spent 127µs making 25 calls to XML::LibXSLT::StylesheetWrapper::close_callback, avg 5µs/call | ||
430 | |||||
431 | if ( defined $mcb and defined $ocb and defined $rcb and defined $ccb ) { | ||||
432 | $icb->register_callbacks( [$mcb, $ocb, $rcb, $ccb] ); | ||||
433 | } | ||||
434 | 25 | 93µs | $self->XML::LibXSLT::lib_init_callbacks(); # spent 93µs making 25 calls to XML::LibXSLT::lib_init_callbacks, avg 4µs/call | ||
435 | 25 | 232µs | $icb->init_callbacks(); # spent 232µs making 25 calls to XML::LibXML::InputCallback::init_callbacks, avg 9µs/call | ||
436 | |||||
437 | my $scb = $self->{XML_LIBXSLT_SECPREFS}; | ||||
438 | if ( $scb ) { | ||||
439 | $scb->init_callbacks(); | ||||
440 | } | ||||
441 | } | ||||
442 | |||||
443 | # spent 924µs (467+457) within XML::LibXSLT::StylesheetWrapper::_cleanup_callbacks which was called 25 times, avg 37µs/call:
# 25 times (467µs+457µs) by XML::LibXSLT::StylesheetWrapper::transform at line 463, avg 37µs/call | ||||
444 | 150 | 449µs | my $self = shift; | ||
445 | 25 | 318µs | $self->{XML_LIBXSLT_CALLBACK_STACK}->cleanup_callbacks(); # spent 318µs making 25 calls to XML::LibXML::InputCallback::cleanup_callbacks, avg 13µs/call | ||
446 | 25 | 138µs | my $mcb = $self->match_callback(); # spent 138µs making 25 calls to XML::LibXSLT::StylesheetWrapper::match_callback, avg 6µs/call | ||
447 | if ( defined $mcb ) { | ||||
448 | $self->{XML_LIBXSLT_CALLBACK_STACK}->unregister_callbacks( [$mcb] ); | ||||
449 | } | ||||
450 | |||||
451 | my $scb = $self->{XML_LIBXSLT_SECPREFS}; | ||||
452 | if ( $scb ) { | ||||
453 | $scb->cleanup_callbacks(); | ||||
454 | } | ||||
455 | } | ||||
456 | |||||
457 | # spent 47.5ms (915µs+46.6) within XML::LibXSLT::StylesheetWrapper::transform which was called 25 times, avg 1.90ms/call:
# 25 times (915µs+46.6ms) by C4::XSLT::XSLTParse4Display at line 240 of /usr/share/koha/lib/C4/XSLT.pm, avg 1.90ms/call | ||||
458 | 225 | 44.5ms | my $self = shift; | ||
459 | my $doc; | ||||
460 | |||||
461 | 25 | 2.01ms | $self->_init_callbacks(); # spent 2.01ms making 25 calls to XML::LibXSLT::StylesheetWrapper::_init_callbacks, avg 80µs/call | ||
462 | 25 | 43.7ms | eval { $doc = $self->{XML_LIBXSLT_STYLESHEET}->transform($self,@_); }; # spent 43.7ms making 25 calls to XML::LibXSLT::Stylesheet::transform, avg 1.75ms/call | ||
463 | 25 | 924µs | $self->_cleanup_callbacks(); # spent 924µs making 25 calls to XML::LibXSLT::StylesheetWrapper::_cleanup_callbacks, avg 37µs/call | ||
464 | |||||
465 | my $err = $@; | ||||
466 | if ($err) { | ||||
467 | croak $err; | ||||
468 | } | ||||
469 | |||||
470 | return $doc; | ||||
471 | } | ||||
472 | |||||
473 | sub transform_file { | ||||
474 | my $self = shift; | ||||
475 | my $doc; | ||||
476 | |||||
477 | $self->_init_callbacks(); | ||||
478 | eval { $doc = $self->{XML_LIBXSLT_STYLESHEET}->transform_file($self,@_); }; | ||||
479 | $self->_cleanup_callbacks(); | ||||
480 | |||||
481 | my $err = $@; | ||||
482 | if ($err) { | ||||
483 | croak $err; | ||||
484 | } | ||||
485 | |||||
486 | return $doc; | ||||
487 | } | ||||
488 | |||||
489 | 25 | 1.82ms | 25 | 1.55ms | # spent 1.79ms (248µs+1.55) within XML::LibXSLT::StylesheetWrapper::output_string which was called 25 times, avg 72µs/call:
# 25 times (248µs+1.55ms) by C4::XSLT::XSLTParse4Display at line 241 of /usr/share/koha/lib/C4/XSLT.pm, avg 72µs/call # spent 1.55ms making 25 calls to XML::LibXSLT::Stylesheet::_output_string, avg 62µs/call |
490 | sub output_as_bytes { shift->{XML_LIBXSLT_STYLESHEET}->_output_string($_[0],1) } | ||||
491 | sub output_as_chars { shift->{XML_LIBXSLT_STYLESHEET}->_output_string($_[0],2) } | ||||
492 | sub output_fh { shift->{XML_LIBXSLT_STYLESHEET}->output_fh(@_) } | ||||
493 | sub output_file { shift->{XML_LIBXSLT_STYLESHEET}->output_file(@_) } | ||||
494 | sub media_type { shift->{XML_LIBXSLT_STYLESHEET}->media_type(@_) } | ||||
495 | sub output_encoding { shift->{XML_LIBXSLT_STYLESHEET}->output_encoding(@_) } | ||||
496 | |||||
497 | 1 | 200ns | 1; | ||
498 | |||||
499 | # XML::LibXSLT::Security Interface # | ||||
500 | #-------------------------------------------------------------------------# | ||||
501 | package XML::LibXSLT::Security; | ||||
502 | |||||
503 | 3 | 60µs | 2 | 41µs | # spent 34µs (26+8) within XML::LibXSLT::Security::BEGIN@503 which was called:
# once (26µs+8µs) by C4::XSLT::BEGIN@35 at line 503 # spent 34µs making 1 call to XML::LibXSLT::Security::BEGIN@503
# spent 8µs making 1 call to strict::import |
504 | 3 | 58µs | 2 | 203µs | # spent 112µs (21+91) within XML::LibXSLT::Security::BEGIN@504 which was called:
# once (21µs+91µs) by C4::XSLT::BEGIN@35 at line 504 # spent 112µs making 1 call to XML::LibXSLT::Security::BEGIN@504
# spent 91µs making 1 call to Exporter::import |
505 | |||||
506 | 3 | 636µs | 2 | 179µs | # spent 99µs (18+81) within XML::LibXSLT::Security::BEGIN@506 which was called:
# once (18µs+81µs) by C4::XSLT::BEGIN@35 at line 506 # spent 99µs making 1 call to XML::LibXSLT::Security::BEGIN@506
# spent 81µs making 1 call to vars::import |
507 | |||||
508 | # Maps the option names used in the perl interface to the numeric values | ||||
509 | # used by libxslt. | ||||
510 | 1 | 8µs | my %OPTION_MAP = ( | ||
511 | read_file => 1, | ||||
512 | write_file => 2, | ||||
513 | create_dir => 3, | ||||
514 | read_net => 4, | ||||
515 | write_net => 5, | ||||
516 | ); | ||||
517 | |||||
518 | 1 | 700ns | %_GLOBAL_CALLBACKS = (); | ||
519 | |||||
520 | |||||
521 | #-------------------------------------------------------------------------# | ||||
522 | # global callback # | ||||
523 | #-------------------------------------------------------------------------# | ||||
524 | sub _security_check { | ||||
525 | my $option = shift; | ||||
526 | my $retval = 1; | ||||
527 | |||||
528 | if ($option == 3) { | ||||
529 | $retval = 0; # Default create_dir to no access | ||||
530 | } | ||||
531 | |||||
532 | if (exists $_GLOBAL_CALLBACKS{$option}) { | ||||
533 | $retval = $_GLOBAL_CALLBACKS{$option}->(@_); | ||||
534 | } | ||||
535 | |||||
536 | return $retval; | ||||
537 | } | ||||
538 | |||||
539 | #-------------------------------------------------------------------------# | ||||
540 | # member functions and methods # | ||||
541 | #-------------------------------------------------------------------------# | ||||
542 | |||||
543 | sub new { | ||||
544 | my $class = shift; | ||||
545 | return bless {'_CALLBACKS' => {}}, $class; | ||||
546 | } | ||||
547 | |||||
548 | # Add a callback for the given security option (read_file, write_file, | ||||
549 | # create_dir, read_net, write_net). | ||||
550 | # | ||||
551 | # To register a callback that handle network read requests: | ||||
552 | # $scb->register_callback( read_net => \&callback ); | ||||
553 | sub register_callback { | ||||
554 | my $self = shift; | ||||
555 | my $option = shift; | ||||
556 | my $callback = shift; | ||||
557 | |||||
558 | unless ( exists $OPTION_MAP{$option} ) { | ||||
559 | croak "Invalid security option '$option'. Must be one of: " . | ||||
560 | join(', ', keys %OPTION_MAP) . "."; | ||||
561 | } | ||||
562 | |||||
563 | if ( ref $callback eq 'CODE' ) { | ||||
564 | $self->{_CALLBACKS}{ $OPTION_MAP{$option} } = $callback; | ||||
565 | } | ||||
566 | else { | ||||
567 | croak "Invalid argument. The callback must be a reference to a subroutine"; | ||||
568 | } | ||||
569 | } | ||||
570 | |||||
571 | # Removes the callback for the given security option. Causes the given option | ||||
572 | # to use the default security handler (which always allows the action). | ||||
573 | sub unregister_callback { | ||||
574 | my $self = shift; | ||||
575 | my $option = shift; | ||||
576 | |||||
577 | unless ( exists $OPTION_MAP{$option} ) { | ||||
578 | croak "Invalid security option '$option'. Must be one of: " . | ||||
579 | join(', ', keys %OPTION_MAP) . "."; | ||||
580 | } | ||||
581 | |||||
582 | delete $self->{_CALLBACKS}{ $OPTION_MAP{$option} }; | ||||
583 | } | ||||
584 | |||||
585 | |||||
586 | # make it so libxslt can use the callbacks | ||||
587 | sub init_callbacks { | ||||
588 | my $self = shift; | ||||
589 | |||||
590 | %_GLOBAL_CALLBACKS = %{ $self->{_CALLBACKS} }; | ||||
591 | } | ||||
592 | |||||
593 | # reset libxslt callbacks | ||||
594 | sub cleanup_callbacks { | ||||
595 | my $self = shift; | ||||
596 | |||||
597 | %_GLOBAL_CALLBACKS = (); | ||||
598 | } | ||||
599 | |||||
600 | 1 | 10µs | 1; | ||
601 | |||||
602 | __END__ | ||||
# spent 10.1ms (10.1+26µs) within XML::LibXSLT::_parse_stylesheet which was called:
# once (10.1ms+26µs) by XML::LibXSLT::parse_stylesheet at line 249 | |||||
# spent 261µs within XML::LibXSLT::bootstrap which was called:
# once (261µs+0s) by DynaLoader::bootstrap at line 215 of DynaLoader.pm | |||||
sub XML::LibXSLT::lib_init_callbacks; # xsub |