Filename | /usr/lib/perl5/XML/LibXSLT.pm |
Statements | Executed 1312 statements in 69.8ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 14.8ms | 14.8ms | _parse_stylesheet (xsub) | XML::LibXSLT::
25 | 1 | 1 | 1.25ms | 2.25ms | _init_callbacks | XML::LibXSLT::StylesheetWrapper::
25 | 1 | 1 | 1.04ms | 50.4ms | transform | XML::LibXSLT::StylesheetWrapper::
25 | 1 | 1 | 517µs | 1.04ms | _cleanup_callbacks | XML::LibXSLT::StylesheetWrapper::
50 | 2 | 1 | 368µs | 368µs | match_callback | XML::LibXSLT::StylesheetWrapper::
25 | 1 | 1 | 262µs | 1.72ms | output_string | XML::LibXSLT::StylesheetWrapper::
1 | 1 | 1 | 190µs | 190µs | bootstrap (xsub) | XML::LibXSLT::
25 | 1 | 1 | 159µs | 159µs | open_callback | XML::LibXSLT::StylesheetWrapper::
25 | 1 | 1 | 153µs | 153µs | read_callback | XML::LibXSLT::StylesheetWrapper::
25 | 1 | 1 | 144µs | 144µs | close_callback | XML::LibXSLT::StylesheetWrapper::
26 | 2 | 1 | 117µs | 117µs | lib_init_callbacks (xsub) | XML::LibXSLT::
1 | 1 | 1 | 55µs | 15.0ms | parse_stylesheet | XML::LibXSLT::
1 | 1 | 1 | 48µs | 93µs | _init_callbacks | XML::LibXSLT::
1 | 1 | 1 | 35µs | 603µs | BEGIN@23 | XML::LibXSLT::
1 | 1 | 1 | 24µs | 31µs | BEGIN@11 | XML::LibXSLT::
1 | 1 | 1 | 20µs | 20µs | new | XML::LibXSLT::
1 | 1 | 1 | 20µs | 427µs | BEGIN@16 | XML::LibXSLT::
1 | 1 | 1 | 19µs | 44µs | _cleanup_callbacks | XML::LibXSLT::
1 | 1 | 1 | 18µs | 23µs | BEGIN@503 | XML::LibXSLT::Security::
1 | 1 | 1 | 17µs | 17µs | BEGIN@17 | XML::LibXSLT::
1 | 1 | 1 | 17µs | 23µs | BEGIN@309 | XML::LibXSLT::StylesheetWrapper::
1 | 1 | 1 | 16µs | 16µs | BEGIN@20 | XML::LibXSLT::
1 | 1 | 1 | 14µs | 14µs | BEGIN@18 | XML::LibXSLT::
1 | 1 | 1 | 14µs | 69µs | BEGIN@24 | XML::LibXSLT::
1 | 1 | 1 | 14µs | 124µs | BEGIN@12 | XML::LibXSLT::
1 | 1 | 1 | 14µs | 106µs | BEGIN@313 | XML::LibXSLT::StylesheetWrapper::
1 | 1 | 1 | 13µs | 13µs | BEGIN@19 | XML::LibXSLT::
1 | 1 | 1 | 12µs | 35µs | BEGIN@79 | XML::LibXSLT::
1 | 1 | 1 | 12µs | 269µs | BEGIN@312 | XML::LibXSLT::StylesheetWrapper::
2 | 2 | 1 | 11µs | 11µs | match_callback | XML::LibXSLT::
1 | 1 | 1 | 11µs | 59µs | BEGIN@504 | XML::LibXSLT::Security::
1 | 1 | 1 | 11µs | 84µs | BEGIN@310 | XML::LibXSLT::StylesheetWrapper::
1 | 1 | 1 | 9µs | 51µs | BEGIN@506 | XML::LibXSLT::Security::
1 | 1 | 1 | 6µs | 6µs | open_callback | XML::LibXSLT::
1 | 1 | 1 | 5µs | 5µs | read_callback | XML::LibXSLT::
1 | 1 | 1 | 4µs | 4µs | close_callback | XML::LibXSLT::
1 | 1 | 1 | 1µs | 1µ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 | 39µs | 2 | 37µs | # spent 31µs (24+7) within XML::LibXSLT::BEGIN@11 which was called:
# once (24µs+7µs) by C4::XSLT::BEGIN@35 at line 11 # spent 31µs making 1 call to XML::LibXSLT::BEGIN@11
# spent 6µs making 1 call to strict::import |
12 | 3 | 59µs | 2 | 235µs | # spent 124µs (14+111) within XML::LibXSLT::BEGIN@12 which was called:
# once (14µs+111µs) by C4::XSLT::BEGIN@35 at line 12 # spent 124µs making 1 call to XML::LibXSLT::BEGIN@12
# spent 111µs making 1 call to vars::import |
13 | |||||
14 | 1 | 3µs | # spent 1µs within XML::LibXSLT::REQUIRE_XML_LIBXML_ABI_VERSION which was called:
# once (1µs+0s) by XML::LibXML::VERSION at line 41 of XML/LibXML.pm | ||
15 | |||||
16 | 3 | 60µs | 3 | 834µs | # spent 427µs (20+407) within XML::LibXSLT::BEGIN@16 which was called:
# once (20µs+407µs) by C4::XSLT::BEGIN@35 at line 16 # spent 427µs making 1 call to XML::LibXSLT::BEGIN@16
# spent 346µs making 1 call to XML::LibXML::import
# spent 61µs making 1 call to XML::LibXML::VERSION |
17 | 3 | 52µs | 1 | 17µs | # spent 17µs within XML::LibXSLT::BEGIN@17 which was called:
# once (17µs+0s) by C4::XSLT::BEGIN@35 at line 17 # spent 17µs making 1 call to XML::LibXSLT::BEGIN@17 |
18 | 3 | 48µs | 1 | 14µs | # spent 14µs within XML::LibXSLT::BEGIN@18 which was called:
# once (14µs+0s) by C4::XSLT::BEGIN@35 at line 18 # spent 14µs making 1 call to XML::LibXSLT::BEGIN@18 |
19 | 3 | 52µs | 1 | 13µs | # spent 13µs within XML::LibXSLT::BEGIN@19 which was called:
# once (13µs+0s) by C4::XSLT::BEGIN@35 at line 19 # spent 13µs making 1 call to XML::LibXSLT::BEGIN@19 |
20 | 3 | 42µs | 1 | 16µs | # spent 16µs within XML::LibXSLT::BEGIN@20 which was called:
# once (16µs+0s) by C4::XSLT::BEGIN@35 at line 20 # spent 16µs making 1 call to XML::LibXSLT::BEGIN@20 |
21 | |||||
22 | |||||
23 | # spent 603µs (35+567) within XML::LibXSLT::BEGIN@23 which was called:
# once (35µs+567µs) by C4::XSLT::BEGIN@35 at line 44 | ||||
24 | 3 | 124µs | 2 | 123µs | # spent 69µs (14+55) within XML::LibXSLT::BEGIN@24 which was called:
# once (14µs+55µs) by C4::XSLT::BEGIN@35 at line 24 # spent 69µs making 1 call to XML::LibXSLT::BEGIN@24
# spent 55µs making 1 call to Exporter::import |
25 | |||||
26 | 8 | 29µ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 | 563µs | bootstrap XML::LibXSLT $VERSION; # spent 563µ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 | 4µs | INIT_THREAD_SUPPORT() if XML::LibXML::threads_shared_enabled(); # spent 4µs making 1 call to XML::LibXML::threads_shared_enabled | ||
43 | $USE_LIBXML_DATA_TYPES = 0; | ||||
44 | 1 | 224µs | 1 | 603µs | } # spent 603µs making 1 call to XML::LibXSLT::BEGIN@23 |
45 | |||||
46 | |||||
47 | # spent 20µs within XML::LibXSLT::new which was called:
# once (20µs+0s) by C4::XSLT::XSLTParse4Display at line 229 of /usr/share/koha/lib/C4/XSLT.pm | ||||
48 | 4 | 21µ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.16ms | 2 | 58µs | # spent 35µs (12+23) within XML::LibXSLT::BEGIN@79 which was called:
# once (12µs+23µs) by C4::XSLT::BEGIN@35 at line 79 # spent 35µs making 1 call to XML::LibXSLT::BEGIN@79
# spent 23µ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 | 4 | 4µs | my $self = shift; | ||
132 | 4 | 12µs | 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 | 2 | 1µs | my $self = shift; | ||
147 | 2 | 5µs | 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 | 2 | 1µs | my $self = shift; | ||
162 | 2 | 7µs | 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 6µs within XML::LibXSLT::open_callback which was called:
# once (6µs+0s) by XML::LibXSLT::_init_callbacks at line 222 | ||||
176 | 2 | 2µs | my $self = shift; | ||
177 | 2 | 6µs | 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 93µs (48+46) within XML::LibXSLT::_init_callbacks which was called:
# once (48µs+46µs) by XML::LibXSLT::parse_stylesheet at line 246 | ||||
213 | 10 | 45µs | my $self = shift; | ||
214 | my $icb = $self->{XML_LIBXSLT_CALLBACK_STACK}; | ||||
215 | |||||
216 | 2 | 4µs | unless ( defined $icb ) { | ||
217 | 1 | 4µs | $self->{XML_LIBXSLT_CALLBACK_STACK} = XML::LibXML::InputCallback->new(); # spent 4µ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 | 6µs | my $ocb = $self->open_callback(); # spent 6µ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 | 15µs | $self->lib_init_callbacks(); # spent 15µs making 1 call to XML::LibXSLT::lib_init_callbacks | ||
231 | 1 | 7µs | $icb->init_callbacks(); # spent 7µs making 1 call to XML::LibXML::InputCallback::init_callbacks | ||
232 | } | ||||
233 | |||||
234 | # spent 44µs (19+25) within XML::LibXSLT::_cleanup_callbacks which was called:
# once (19µs+25µs) by XML::LibXSLT::parse_stylesheet at line 251 | ||||
235 | 4 | 15µs | my $self = shift; | ||
236 | 1 | 19µs | $self->{XML_LIBXSLT_CALLBACK_STACK}->cleanup_callbacks(); # spent 19µs making 1 call to XML::LibXML::InputCallback::cleanup_callbacks | ||
237 | 1 | 6µs | my $mcb = $self->match_callback(); # spent 6µ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 15.0ms (55µs+14.9) within XML::LibXSLT::parse_stylesheet which was called:
# once (55µs+14.9ms) by C4::XSLT::XSLTParse4Display at line 238 of /usr/share/koha/lib/C4/XSLT.pm | ||||
244 | 9 | 41µs | my $self = shift; | ||
245 | |||||
246 | 1 | 93µs | $self->_init_callbacks(); # spent 93µs making 1 call to XML::LibXSLT::_init_callbacks | ||
247 | |||||
248 | my $stylesheet; | ||||
249 | 1 | 14.8ms | 3 | 14.8ms | eval { $stylesheet = $self->_parse_stylesheet(@_); }; # spent 14.8ms making 1 call to XML::LibXSLT::_parse_stylesheet
# spent 27µs making 2 calls to XML::LibXML::InputCallback::_callback_match, avg 13µs/call |
250 | |||||
251 | 1 | 44µs | $self->_cleanup_callbacks(); # spent 44µ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 | 200ns | 1; | ||
306 | |||||
307 | package XML::LibXSLT::StylesheetWrapper; | ||||
308 | |||||
309 | 3 | 34µs | 2 | 29µs | # spent 23µs (17+6) within XML::LibXSLT::StylesheetWrapper::BEGIN@309 which was called:
# once (17µs+6µs) by C4::XSLT::BEGIN@35 at line 309 # spent 23µs making 1 call to XML::LibXSLT::StylesheetWrapper::BEGIN@309
# spent 6µs making 1 call to strict::import |
310 | 3 | 33µs | 2 | 157µs | # spent 84µs (11+73) within XML::LibXSLT::StylesheetWrapper::BEGIN@310 which was called:
# once (11µs+73µs) by C4::XSLT::BEGIN@35 at line 310 # spent 84µs making 1 call to XML::LibXSLT::StylesheetWrapper::BEGIN@310
# spent 73µs making 1 call to vars::import |
311 | |||||
312 | 3 | 36µs | 2 | 526µs | # spent 269µs (12+257) within XML::LibXSLT::StylesheetWrapper::BEGIN@312 which was called:
# once (12µs+257µs) by C4::XSLT::BEGIN@35 at line 312 # spent 269µs making 1 call to XML::LibXSLT::StylesheetWrapper::BEGIN@312
# spent 257µs making 1 call to XML::LibXML::import |
313 | 3 | 982µs | 2 | 199µs | # spent 106µs (14+93) within XML::LibXSLT::StylesheetWrapper::BEGIN@313 which was called:
# once (14µs+93µs) by C4::XSLT::BEGIN@35 at line 313 # spent 106µs making 1 call to XML::LibXSLT::StylesheetWrapper::BEGIN@313
# spent 93µ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 368µs within XML::LibXSLT::StylesheetWrapper::match_callback which was called 50 times, avg 7µs/call:
# 25 times (188µs+0s) by XML::LibXSLT::StylesheetWrapper::_cleanup_callbacks at line 446, avg 8µs/call
# 25 times (180µs+0s) by XML::LibXSLT::StylesheetWrapper::_init_callbacks at line 426, avg 7µs/call | ||||
336 | 100 | 138µs | my $self = shift; | ||
337 | 100 | 323µs | 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 153µs within XML::LibXSLT::StylesheetWrapper::read_callback which was called 25 times, avg 6µs/call:
# 25 times (153µs+0s) by XML::LibXSLT::StylesheetWrapper::_init_callbacks at line 428, avg 6µs/call | ||||
351 | 50 | 46µs | my $self = shift; | ||
352 | 50 | 162µs | 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 144µs within XML::LibXSLT::StylesheetWrapper::close_callback which was called 25 times, avg 6µs/call:
# 25 times (144µs+0s) by XML::LibXSLT::StylesheetWrapper::_init_callbacks at line 429, avg 6µs/call | ||||
366 | 50 | 45µs | my $self = shift; | ||
367 | 50 | 129µs | 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 159µs within XML::LibXSLT::StylesheetWrapper::open_callback which was called 25 times, avg 6µs/call:
# 25 times (159µs+0s) by XML::LibXSLT::StylesheetWrapper::_init_callbacks at line 427, avg 6µs/call | ||||
381 | 50 | 44µs | my $self = shift; | ||
382 | 50 | 148µs | 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.25ms (1.25+1.00) within XML::LibXSLT::StylesheetWrapper::_init_callbacks which was called 25 times, avg 90µs/call:
# 25 times (1.25ms+1.00ms) by XML::LibXSLT::StylesheetWrapper::transform at line 461, avg 90µs/call | ||||
418 | 300 | 1.24ms | 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 | 180µs | my $mcb = $self->match_callback(); # spent 180µs making 25 calls to XML::LibXSLT::StylesheetWrapper::match_callback, avg 7µs/call | ||
427 | 25 | 159µs | my $ocb = $self->open_callback(); # spent 159µs making 25 calls to XML::LibXSLT::StylesheetWrapper::open_callback, avg 6µs/call | ||
428 | 25 | 153µs | my $rcb = $self->read_callback(); # spent 153µs making 25 calls to XML::LibXSLT::StylesheetWrapper::read_callback, avg 6µs/call | ||
429 | 25 | 144µs | my $ccb = $self->close_callback(); # spent 144µs making 25 calls to XML::LibXSLT::StylesheetWrapper::close_callback, avg 6µ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 | 102µs | $self->XML::LibXSLT::lib_init_callbacks(); # spent 102µs making 25 calls to XML::LibXSLT::lib_init_callbacks, avg 4µs/call | ||
435 | 25 | 266µs | $icb->init_callbacks(); # spent 266µs making 25 calls to XML::LibXML::InputCallback::init_callbacks, avg 11µs/call | ||
436 | |||||
437 | my $scb = $self->{XML_LIBXSLT_SECPREFS}; | ||||
438 | if ( $scb ) { | ||||
439 | $scb->init_callbacks(); | ||||
440 | } | ||||
441 | } | ||||
442 | |||||
443 | # spent 1.04ms (517µs+521µs) within XML::LibXSLT::StylesheetWrapper::_cleanup_callbacks which was called 25 times, avg 42µs/call:
# 25 times (517µs+521µs) by XML::LibXSLT::StylesheetWrapper::transform at line 463, avg 42µs/call | ||||
444 | 150 | 393µs | my $self = shift; | ||
445 | 25 | 334µs | $self->{XML_LIBXSLT_CALLBACK_STACK}->cleanup_callbacks(); # spent 334µs making 25 calls to XML::LibXML::InputCallback::cleanup_callbacks, avg 13µs/call | ||
446 | 25 | 188µs | my $mcb = $self->match_callback(); # spent 188µs making 25 calls to XML::LibXSLT::StylesheetWrapper::match_callback, avg 8µ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 50.4ms (1.04+49.3) within XML::LibXSLT::StylesheetWrapper::transform which was called 25 times, avg 2.02ms/call:
# 25 times (1.04ms+49.3ms) by C4::XSLT::XSLTParse4Display at line 240 of /usr/share/koha/lib/C4/XSLT.pm, avg 2.02ms/call | ||||
458 | 200 | 630µs | my $self = shift; | ||
459 | my $doc; | ||||
460 | |||||
461 | 25 | 2.25ms | $self->_init_callbacks(); # spent 2.25ms making 25 calls to XML::LibXSLT::StylesheetWrapper::_init_callbacks, avg 90µs/call | ||
462 | 25 | 46.4ms | 25 | 46.1ms | eval { $doc = $self->{XML_LIBXSLT_STYLESHEET}->transform($self,@_); }; # spent 46.1ms making 25 calls to XML::LibXSLT::Stylesheet::transform, avg 1.84ms/call |
463 | 25 | 1.04ms | $self->_cleanup_callbacks(); # spent 1.04ms making 25 calls to XML::LibXSLT::StylesheetWrapper::_cleanup_callbacks, avg 42µ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.74ms | 25 | 1.46ms | # spent 1.72ms (262µs+1.46) within XML::LibXSLT::StylesheetWrapper::output_string which was called 25 times, avg 69µs/call:
# 25 times (262µs+1.46ms) by C4::XSLT::XSLTParse4Display at line 241 of /usr/share/koha/lib/C4/XSLT.pm, avg 69µs/call # spent 1.46ms making 25 calls to XML::LibXSLT::Stylesheet::_output_string, avg 58µ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 | 100ns | 1; | ||
498 | |||||
499 | # XML::LibXSLT::Security Interface # | ||||
500 | #-------------------------------------------------------------------------# | ||||
501 | package XML::LibXSLT::Security; | ||||
502 | |||||
503 | 3 | 30µs | 2 | 28µs | # spent 23µs (18+5) within XML::LibXSLT::Security::BEGIN@503 which was called:
# once (18µs+5µs) by C4::XSLT::BEGIN@35 at line 503 # spent 23µs making 1 call to XML::LibXSLT::Security::BEGIN@503
# spent 5µs making 1 call to strict::import |
504 | 3 | 39µs | 2 | 106µs | # spent 59µs (11+48) within XML::LibXSLT::Security::BEGIN@504 which was called:
# once (11µs+48µs) by C4::XSLT::BEGIN@35 at line 504 # spent 59µs making 1 call to XML::LibXSLT::Security::BEGIN@504
# spent 48µs making 1 call to Exporter::import |
505 | |||||
506 | 3 | 367µs | 2 | 92µs | # spent 51µs (9+42) within XML::LibXSLT::Security::BEGIN@506 which was called:
# once (9µs+42µs) by C4::XSLT::BEGIN@35 at line 506 # spent 51µs making 1 call to XML::LibXSLT::Security::BEGIN@506
# spent 42µ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 | 5µ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 | 400ns | %_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 | 6µs | 1; | ||
601 | |||||
602 | __END__ | ||||
# spent 14.8ms (14.8+27µs) within XML::LibXSLT::_parse_stylesheet which was called:
# once (14.8ms+27µs) by XML::LibXSLT::parse_stylesheet at line 249 | |||||
# spent 190µs within XML::LibXSLT::bootstrap which was called:
# once (190µs+0s) by DynaLoader::bootstrap at line 215 of DynaLoader.pm | |||||
sub XML::LibXSLT::lib_init_callbacks; # xsub |