← Index
NYTProf Performance Profile   « block view • line view • sub view »
For 01.HTTP.t
  Run on Tue May 4 14:17:45 2010
Reported on Tue May 4 14:18:22 2010

File /usr/local/lib/perl5/site_perl/5.10.1/XML/SAX.pm
Statements Executed 156
Statement Execution Time 1.97ms
Subroutines — ordered by exclusive time
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1111.83ms2.18msXML::SAX::::BEGIN@15XML::SAX::BEGIN@15
111732µs1.69msXML::SAX::::BEGIN@18XML::SAX::BEGIN@18
111192µs337µsXML::SAX::::_parse_ini_fileXML::SAX::_parse_ini_file
363273µs73µsXML::SAX::::CORE:substXML::SAX::CORE:subst (opcode)
11158µs607µsXML::SAX::::load_parsersXML::SAX::load_parsers
252249µs49µsXML::SAX::::CORE:matchXML::SAX::CORE:match (opcode)
11236µs36µsXML::SAX::::CORE:openXML::SAX::CORE:open (opcode)
11125µs33µsXML::SAX::::BEGIN@5XML::SAX::BEGIN@5
131222µs22µsXML::SAX::::CORE:readlineXML::SAX::CORE:readline (opcode)
31121µs628µsXML::SAX::::parsersXML::SAX::parsers
11112µs72µsXML::SAX::::BEGIN@20XML::SAX::BEGIN@20
11112µs101µsXML::SAX::::BEGIN@6XML::SAX::BEGIN@6
11110µs62µsXML::SAX::::BEGIN@17XML::SAX::BEGIN@17
1119µs42µsXML::SAX::::BEGIN@22XML::SAX::BEGIN@22
1119µs40µsXML::SAX::::BEGIN@23XML::SAX::BEGIN@23
1116µs6µsXML::SAX::::BEGIN@10XML::SAX::BEGIN@10
1116µs6µsXML::SAX::::BEGIN@16XML::SAX::BEGIN@16
0000s0sXML::SAX::::add_parserXML::SAX::add_parser
0000s0sXML::SAX::::do_warnXML::SAX::do_warn
0000s0sXML::SAX::::remove_parserXML::SAX::remove_parser
0000s0sXML::SAX::::save_parsersXML::SAX::save_parsers
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# $Id: SAX.pm,v 1.31 2008-08-05 12:36:24 grant Exp $
2
3package XML::SAX;
4
5347µs240µs
# spent 33µs (25+8) within XML::SAX::BEGIN@5 which was called # once (25µs+8µs) by XML::Simple::build_tree at line 5
use strict;
# spent 33µs making 1 call to XML::SAX::BEGIN@5 # spent 8µs making 1 call to strict::import
6353µs2191µs
# spent 101µs (12+90) within XML::SAX::BEGIN@6 which was called # once (12µs+90µs) by XML::Simple::build_tree at line 6
use vars qw($VERSION @ISA @EXPORT_OK);
# spent 101µs making 1 call to XML::SAX::BEGIN@6 # spent 90µs making 1 call to vars::import
7
81700ns$VERSION = '0.96';
9
10359µs16µs
# spent 6µs within XML::SAX::BEGIN@10 which was called # once (6µs+0s) by XML::Simple::build_tree at line 10
use Exporter ();
# spent 6µs making 1 call to XML::SAX::BEGIN@10
11110µs@ISA = ('Exporter');
12
131900ns@EXPORT_OK = qw(Namespaces Validation);
14
153213µs22.24ms
# spent 2.18ms (1.83+344µs) within XML::SAX::BEGIN@15 which was called # once (1.83ms+344µs) by XML::Simple::build_tree at line 15
use File::Basename qw(dirname);
# spent 2.18ms making 1 call to XML::SAX::BEGIN@15 # spent 66µs making 1 call to Exporter::import
16327µs16µs
# spent 6µs within XML::SAX::BEGIN@16 which was called # once (6µs+0s) by XML::Simple::build_tree at line 16
use File::Spec ();
# spent 6µs making 1 call to XML::SAX::BEGIN@16
17329µs2114µs
# spent 62µs (10+52) within XML::SAX::BEGIN@17 which was called # once (10µs+52µs) by XML::Simple::build_tree at line 17
use Symbol qw(gensym);
# spent 62µs making 1 call to XML::SAX::BEGIN@17 # spent 52µs making 1 call to Exporter::import
183146µs11.69ms
# spent 1.69ms (732µs+963µs) within XML::SAX::BEGIN@18 which was called # once (732µs+963µs) by XML::Simple::build_tree at line 18
use XML::SAX::ParserFactory (); # loaded for simplicity
# spent 1.69ms making 1 call to XML::SAX::BEGIN@18
19
20337µs2133µs
# spent 72µs (12+61) within XML::SAX::BEGIN@20 which was called # once (12µs+61µs) by XML::Simple::build_tree at line 20
use constant PARSER_DETAILS => "ParserDetails.ini";
# spent 72µs making 1 call to XML::SAX::BEGIN@20 # spent 60µs making 1 call to constant::import
21
22331µs275µs
# spent 42µs (9+33) within XML::SAX::BEGIN@22 which was called # once (9µs+33µs) by XML::Simple::build_tree at line 22
use constant Namespaces => "http://xml.org/sax/features/namespaces";
# spent 42µs making 1 call to XML::SAX::BEGIN@22 # spent 33µs making 1 call to constant::import
233872µs272µs
# spent 40µs (9+32) within XML::SAX::BEGIN@23 which was called # once (9µs+32µs) by XML::Simple::build_tree at line 23
use constant Validation => "http://xml.org/sax/features/validation";
# spent 40µs making 1 call to XML::SAX::BEGIN@23 # spent 32µs making 1 call to constant::import
24
251400nsmy $known_parsers = undef;
26
27# load_parsers takes the ParserDetails.ini file out of the same directory
28# that XML::SAX is in, and looks at it. Format in POD below
29
30=begin EXAMPLE
31
32[XML::SAX::PurePerl]
33http://xml.org/sax/features/namespaces = 1
34http://xml.org/sax/features/validation = 0
35# a comment
36
37# blank lines ignored
38
39[XML::SAX::AnotherParser]
40http://xml.org/sax/features/namespaces = 0
41http://xml.org/sax/features/validation = 1
42
43=end EXAMPLE
44
45=cut
46
47
# spent 607µs (58+550) within XML::SAX::load_parsers which was called # once (58µs+550µs) by XML::SAX::parsers at line 114
sub load_parsers {
481400ns my $class = shift;
491200ns my $dir = shift;
50
51 # reset parsers
521500ns $known_parsers = [];
53
54 # get directory from wherever XML::SAX is installed
551500ns if (!$dir) {
561700ns $dir = $INC{'XML/SAX.pm'};
5712µs174µs $dir = dirname($dir);
# spent 74µs making 1 call to File::Basename::dirname
58 }
59
6012µs111µs my $fh = gensym();
# spent 11µs making 1 call to Symbol::gensym
61153µs2128µs if (!open($fh, File::Spec->catfile($dir, "SAX", PARSER_DETAILS))) {
# spent 92µs making 1 call to File::Spec::Unix::catfile # spent 36µs making 1 call to XML::SAX::CORE:open
62 XML::SAX->do_warn("could not find " . PARSER_DETAILS . " in $dir/SAX\n");
63 return $class;
64 }
65
6614µs1337µs $known_parsers = $class->_parse_ini_file($fh);
# spent 337µs making 1 call to XML::SAX::_parse_ini_file
67
68130µs return $class;
69}
70
71
# spent 337µs (192+144) within XML::SAX::_parse_ini_file which was called # once (192µs+144µs) by XML::SAX::load_parsers at line 66
sub _parse_ini_file {
721900ns my $class = shift;
731500ns my ($fh) = @_;
74
751200ns my @config;
76
771200ns my $lineno = 0;
78153µs1322µs while (defined(my $line = <$fh>)) {
# spent 22µs making 13 calls to XML::SAX::CORE:readline, avg 2µs/call
79121µs $lineno++;
80124µs my $original = $line;
81 # strip whitespace
821283µs1261µs $line =~ s/\s*$//m;
# spent 61µs making 12 calls to XML::SAX::CORE:subst, avg 5µs/call
831225µs127µs $line =~ s/^\s*//m;
# spent 7µs making 12 calls to XML::SAX::CORE:subst, avg 550ns/call
84 # strip comments
851222µs126µs $line =~ s/[#;].*$//m;
# spent 6µs making 12 calls to XML::SAX::CORE:subst, avg 483ns/call
86 # ignore blanks
871228µs126µs next if $line =~ /^$/m;
# spent 6µs making 12 calls to XML::SAX::CORE:match, avg 492ns/call
88
89 # heading
90874µs1343µs if ($line =~ /^\[\s*(.*)\s*\]$/m) {
# spent 43µs making 13 calls to XML::SAX::CORE:match, avg 3µs/call
91313µs push @config, { Name => $1 };
9232µs next;
93 }
94
95 # instruction
96 elsif ($line =~ /^(.*?)\s*?=\s*(.*)$/) {
9752µs unless(@config) {
98 push @config, { Name => '' };
99 }
100514µs $config[-1]{Features}{$1} = $2;
101 }
102
103 # not whitespace, comment, or instruction
104 else {
105 die "Invalid line in ini: $lineno\n>>> $original\n";
106 }
107 }
108
10914µs return \@config;
110}
111
112
# spent 628µs (21+607) within XML::SAX::parsers which was called 3 times, avg 209µs/call: # 3 times (21µs+607µs) by XML::SAX::ParserFactory::new at line 18 of XML/SAX/ParserFactory.pm, avg 209µs/call
sub parsers {
11332µs my $class = shift;
11432µs1607µs if (!$known_parsers) {
# spent 607µs making 1 call to XML::SAX::load_parsers
115 $class->load_parsers();
116 }
117312µs return $known_parsers;
118}
119
120sub remove_parser {
121 my $class = shift;
122 my ($parser_module) = @_;
123
124 if (!$known_parsers) {
125 $class->load_parsers();
126 }
127
128 @$known_parsers = grep { $_->{Name} ne $parser_module } @$known_parsers;
129
130 return $class;
131}
132
133sub add_parser {
134 my $class = shift;
135 my ($parser_module) = @_;
136
137 if (!$known_parsers) {
138 $class->load_parsers();
139 }
140
141 # first load module, then query features, then push onto known_parsers,
142
143 my $parser_file = $parser_module;
144 $parser_file =~ s/::/\//g;
145 $parser_file .= ".pm";
146
147 require $parser_file;
148
149 my @features = $parser_module->supported_features();
150
151 my $new = { Name => $parser_module };
152 foreach my $feature (@features) {
153 $new->{Features}{$feature} = 1;
154 }
155
156 # If exists in list already, move to end.
157 my $done = 0;
158 my $pos = undef;
159 for (my $i = 0; $i < @$known_parsers; $i++) {
160 my $p = $known_parsers->[$i];
161 if ($p->{Name} eq $parser_module) {
162 $pos = $i;
163 }
164 }
165 if (defined $pos) {
166 splice(@$known_parsers, $pos, 1);
167 push @$known_parsers, $new;
168 $done++;
169 }
170
171 # Otherwise (not in list), add at end of list.
172 if (!$done) {
173 push @$known_parsers, $new;
174 }
175
176 return $class;
177}
178
179sub save_parsers {
180 my $class = shift;
181
182 # get directory from wherever XML::SAX is installed
183 my $dir = $INC{'XML/SAX.pm'};
184 $dir = dirname($dir);
185
186 my $file = File::Spec->catfile($dir, "SAX", PARSER_DETAILS);
187 chmod 0644, $file;
188 unlink($file);
189
190 my $fh = gensym();
191 open($fh, ">$file") ||
192 die "Cannot write to $file: $!";
193
194 foreach my $p (@$known_parsers) {
195 print $fh "[$p->{Name}]\n";
196 foreach my $key (keys %{$p->{Features}}) {
197 print $fh "$key = $p->{Features}{$key}\n";
198 }
199 print $fh "\n";
200 }
201
202 print $fh "\n";
203
204 close $fh;
205
206 return $class;
207}
208
209sub do_warn {
210 my $class = shift;
211 # Don't output warnings if running under Test::Harness
212 warn(@_) unless $ENV{HARNESS_ACTIVE};
213}
214
21519µs1;
216__END__
217
218=head1 NAME
219
220XML::SAX - Simple API for XML
221
222=head1 SYNOPSIS
223
224 use XML::SAX;
225
226 # get a list of known parsers
227 my $parsers = XML::SAX->parsers();
228
229 # add/update a parser
230 XML::SAX->add_parser(q(XML::SAX::PurePerl));
231
232 # remove parser
233 XML::SAX->remove_parser(q(XML::SAX::Foodelberry));
234
235 # save parsers
236 XML::SAX->save_parsers();
237
238=head1 DESCRIPTION
239
240XML::SAX is a SAX parser access API for Perl. It includes classes
241and APIs required for implementing SAX drivers, along with a factory
242class for returning any SAX parser installed on the user's system.
243
244=head1 USING A SAX2 PARSER
245
246The factory class is XML::SAX::ParserFactory. Please see the
247documentation of that module for how to instantiate a SAX parser:
248L<XML::SAX::ParserFactory>. However if you don't want to load up
249another manual page, here's a short synopsis:
250
251 use XML::SAX::ParserFactory;
252 use XML::SAX::XYZHandler;
253 my $handler = XML::SAX::XYZHandler->new();
254 my $p = XML::SAX::ParserFactory->parser(Handler => $handler);
255 $p->parse_uri("foo.xml");
256 # or $p->parse_string("<foo/>") or $p->parse_file($fh);
257
258This will automatically load a SAX2 parser (defaulting to
259XML::SAX::PurePerl if no others are found) and return it to you.
260
261In order to learn how to use SAX to parse XML, you will need to read
262L<XML::SAX::Intro> and for reference, L<XML::SAX::Specification>.
263
264=head1 WRITING A SAX2 PARSER
265
266The first thing to remember in writing a SAX2 parser is to subclass
267XML::SAX::Base. This will make your life infinitely easier, by providing
268a number of methods automagically for you. See L<XML::SAX::Base> for more
269details.
270
271When writing a SAX2 parser that is compatible with XML::SAX, you need
272to inform XML::SAX of the presence of that driver when you install it.
273In order to do that, XML::SAX contains methods for saving the fact that
274the parser exists on your system to a "INI" file, which is then loaded
275to determine which parsers are installed.
276
277The best way to do this is to follow these rules:
278
279=over 4
280
281=item * Add XML::SAX as a prerequisite in Makefile.PL:
282
283 WriteMakefile(
284 ...
285 PREREQ_PM => { 'XML::SAX' => 0 },
286 ...
287 );
288
289Alternatively you may wish to check for it in other ways that will
290cause more than just a warning.
291
292=item * Add the following code snippet to your Makefile.PL:
293
294 sub MY::install {
295 package MY;
296 my $script = shift->SUPER::install(@_);
297 if (ExtUtils::MakeMaker::prompt(
298 "Do you want to modify ParserDetails.ini?", 'Y')
299 =~ /^y/i) {
300 $script =~ s/install :: (.*)$/install :: $1 install_sax_driver/m;
301 $script .= <<"INSTALL";
302
303 install_sax_driver :
304 \t\@\$(PERL) -MXML::SAX -e "XML::SAX->add_parser(q(\$(NAME)))->save_parsers()"
305
306 INSTALL
307 }
308 return $script;
309 }
310
311Note that you should check the output of this - \$(NAME) will use the name of
312your distribution, which may not be exactly what you want. For example XML::LibXML
313has a driver called XML::LibXML::SAX::Generator, which is used in place of
314\$(NAME) in the above.
315
316=item * Add an XML::SAX test:
317
318A test file should be added to your t/ directory containing something like the
319following:
320
321 use Test;
322 BEGIN { plan tests => 3 }
323 use XML::SAX;
324 use XML::SAX::PurePerl::DebugHandler;
325 XML::SAX->add_parser(q(XML::SAX::MyDriver));
326 local $XML::SAX::ParserPackage = 'XML::SAX::MyDriver';
327 eval {
328 my $handler = XML::SAX::PurePerl::DebugHandler->new();
329 ok($handler);
330 my $parser = XML::SAX::ParserFactory->parser(Handler => $handler);
331 ok($parser);
332 ok($parser->isa('XML::SAX::MyDriver');
333 $parser->parse_string("<tag/>");
334 ok($handler->{seen}{start_element});
335 };
336
337=back
338
339=head1 EXPORTS
340
341By default, XML::SAX exports nothing into the caller's namespace. However you
342can request the symbols C<Namespaces> and C<Validation> which are the
343URIs for those features, allowing an easier way to request those features
344via ParserFactory:
345
346 use XML::SAX qw(Namespaces Validation);
347 my $factory = XML::SAX::ParserFactory->new();
348 $factory->require_feature(Namespaces);
349 $factory->require_feature(Validation);
350 my $parser = $factory->parser();
351
352=head1 AUTHOR
353
354Current maintainer: Grant McLean, grantm@cpan.org
355
356Originally written by:
357
358Matt Sergeant, matt@sergeant.org
359
360Kip Hampton, khampton@totalcinema.com
361
362Robin Berjon, robin@knowscape.com
363
364=head1 LICENSE
365
366This is free software, you may use it and distribute it under
367the same terms as Perl itself.
368
369=head1 SEE ALSO
370
371L<XML::SAX::Base> for writing SAX Filters and Parsers
372
373L<XML::SAX::PurePerl> for an XML parser written in 100%
374pure perl.
375
376L<XML::SAX::Exception> for details on exception handling
377
378=cut
379
# spent 49µs within XML::SAX::CORE:match which was called 25 times, avg 2µs/call: # 13 times (43µs+0s) by XML::SAX::_parse_ini_file at line 90 of XML/SAX.pm, avg 3µs/call # 12 times (6µs+0s) by XML::SAX::_parse_ini_file at line 87 of XML/SAX.pm, avg 492ns/call
sub XML::SAX::CORE:match; # xsub
# spent 36µs within XML::SAX::CORE:open which was called # once (36µs+0s) by XML::SAX::load_parsers at line 61 of XML/SAX.pm
sub XML::SAX::CORE:open; # xsub
# spent 22µs within XML::SAX::CORE:readline which was called 13 times, avg 2µs/call: # 13 times (22µs+0s) by XML::SAX::_parse_ini_file at line 78 of XML/SAX.pm, avg 2µs/call
sub XML::SAX::CORE:readline; # xsub
# spent 73µs within XML::SAX::CORE:subst which was called 36 times, avg 2µs/call: # 12 times (61µs+0s) by XML::SAX::_parse_ini_file at line 82 of XML/SAX.pm, avg 5µs/call # 12 times (7µs+0s) by XML::SAX::_parse_ini_file at line 83 of XML/SAX.pm, avg 550ns/call # 12 times (6µs+0s) by XML::SAX::_parse_ini_file at line 85 of XML/SAX.pm, avg 483ns/call
sub XML::SAX::CORE:subst; # xsub