Filename | /usr/share/perl5/Convert/ASN1.pm |
Statements | Executed 481 statements in 4.81ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 11.8ms | 13.8ms | BEGIN@415 | Convert::ASN1::
74 | 1 | 1 | 638µs | 638µs | asn_tag | Convert::ASN1::
1 | 1 | 1 | 267µs | 271µs | BEGIN@16 | Convert::ASN1::
105 | 3 | 1 | 216µs | 216µs | asn_encode_tag | Convert::ASN1::
1 | 1 | 1 | 89µs | 89µs | _internal_syms | Convert::ASN1::
1 | 1 | 1 | 67µs | 67µs | BEGIN@9 | Convert::ASN1::
1 | 1 | 1 | 34µs | 103ms | prepare | Convert::ASN1::
1 | 1 | 1 | 28µs | 137µs | BEGIN@14 | Convert::ASN1::
1 | 1 | 1 | 26µs | 31µs | configure | Convert::ASN1::
2 | 1 | 1 | 24µs | 24µs | find | Convert::ASN1::
1 | 1 | 1 | 23µs | 211µs | BEGIN@11 | Convert::ASN1::
1 | 1 | 1 | 23µs | 57µs | BEGIN@12 | Convert::ASN1::
1 | 1 | 1 | 21µs | 32µs | BEGIN@10 | Convert::ASN1::
1 | 1 | 1 | 21µs | 52µs | new | Convert::ASN1::
1 | 1 | 1 | 16µs | 38µs | BEGIN@67 | Convert::ASN1::
1 | 1 | 1 | 15µs | 49µs | BEGIN@59 | Convert::ASN1::
1 | 1 | 1 | 5µs | 5µs | CORE:match (opcode) | Convert::ASN1::
1 | 1 | 1 | 3µs | 3µs | _pack_struct | Convert::ASN1::
0 | 0 | 0 | 0s | 0s | AUTOLOAD | Convert::ASN1::
0 | 0 | 0 | 0s | 0s | DESTROY | Convert::ASN1::
0 | 0 | 0 | 0s | 0s | __ANON__[:60] | Convert::ASN1::
0 | 0 | 0 | 0s | 0s | _unpack_struct | Convert::ASN1::
0 | 0 | 0 | 0s | 0s | asn_decode_length | Convert::ASN1::
0 | 0 | 0 | 0s | 0s | asn_decode_tag | Convert::ASN1::
0 | 0 | 0 | 0s | 0s | asn_decode_tag2 | Convert::ASN1::
0 | 0 | 0 | 0s | 0s | asn_encode_length | Convert::ASN1::
0 | 0 | 0 | 0s | 0s | decode | Convert::ASN1::
0 | 0 | 0 | 0s | 0s | encode | Convert::ASN1::
0 | 0 | 0 | 0s | 0s | error | Convert::ASN1::
0 | 0 | 0 | 0s | 0s | i2osp | Convert::ASN1::
0 | 0 | 0 | 0s | 0s | num_length | Convert::ASN1::
0 | 0 | 0 | 0s | 0s | os2ip | Convert::ASN1::
0 | 0 | 0 | 0s | 0s | prepare_file | Convert::ASN1::
0 | 0 | 0 | 0s | 0s | registeroid | Convert::ASN1::
0 | 0 | 0 | 0s | 0s | registertype | Convert::ASN1::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | # Copyright (c) 2000-2002 Graham Barr <gbarr@pobox.com>. All rights reserved. | ||||
2 | # This program is free software; you can redistribute it and/or | ||||
3 | # modify it under the same terms as Perl itself. | ||||
4 | |||||
5 | package Convert::ASN1; | ||||
6 | |||||
7 | # $Id: ASN1.pm,v 1.29 2003/10/08 14:29:17 gbarr Exp $ | ||||
8 | |||||
9 | 3 | 88µs | 1 | 67µs | # spent 67µs within Convert::ASN1::BEGIN@9 which was called:
# once (67µs+0s) by Net::LDAP::BEGIN@12 at line 9 # spent 67µs making 1 call to Convert::ASN1::BEGIN@9 |
10 | 3 | 111µs | 2 | 42µs | # spent 32µs (21+10) within Convert::ASN1::BEGIN@10 which was called:
# once (21µs+10µs) by Net::LDAP::BEGIN@12 at line 10 # spent 32µs making 1 call to Convert::ASN1::BEGIN@10
# spent 10µs making 1 call to strict::import |
11 | 3 | 57µs | 2 | 399µs | # spent 211µs (23+188) within Convert::ASN1::BEGIN@11 which was called:
# once (23µs+188µs) by Net::LDAP::BEGIN@12 at line 11 # spent 211µs making 1 call to Convert::ASN1::BEGIN@11
# spent 188µs making 1 call to vars::import |
12 | 3 | 74µs | 2 | 91µs | # spent 57µs (23+34) within Convert::ASN1::BEGIN@12 which was called:
# once (23µs+34µs) by Net::LDAP::BEGIN@12 at line 12 # spent 57µs making 1 call to Convert::ASN1::BEGIN@12
# spent 34µs making 1 call to Exporter::import |
13 | |||||
14 | 3 | 336µs | 2 | 247µs | # spent 137µs (28+109) within Convert::ASN1::BEGIN@14 which was called:
# once (28µs+109µs) by Net::LDAP::BEGIN@12 at line 14 # spent 137µs making 1 call to Convert::ASN1::BEGIN@14
# spent 109µs making 1 call to constant::import |
15 | |||||
16 | # spent 271µs (267+4) within Convert::ASN1::BEGIN@16 which was called:
# once (267µs+4µs) by Net::LDAP::BEGIN@12 at line 63 | ||||
17 | 1 | 5µs | local $SIG{__DIE__}; | ||
18 | 2 | 9µs | 1 | 4µs | eval { require bytes and 'bytes'->import }; # spent 4µs making 1 call to bytes::import |
19 | |||||
20 | 1 | 500ns | if (CHECK_UTF8) { | ||
21 | 1 | 900ns | require Encode; | ||
22 | 1 | 1µs | require utf8; | ||
23 | } | ||||
24 | |||||
25 | 1 | 9µs | @ISA = qw(Exporter); | ||
26 | 1 | 600ns | $VERSION = "0.22"; | ||
27 | |||||
28 | 1 | 14µs | %EXPORT_TAGS = ( | ||
29 | io => [qw(asn_recv asn_send asn_read asn_write asn_get asn_ready)], | ||||
30 | |||||
31 | debug => [qw(asn_dump asn_hexdump)], | ||||
32 | |||||
33 | const => [qw(ASN_BOOLEAN ASN_INTEGER ASN_BIT_STR ASN_OCTET_STR | ||||
34 | ASN_NULL ASN_OBJECT_ID ASN_REAL ASN_ENUMERATED | ||||
35 | ASN_SEQUENCE ASN_SET ASN_PRINT_STR ASN_IA5_STR | ||||
36 | ASN_UTC_TIME ASN_GENERAL_TIME ASN_RELATIVE_OID | ||||
37 | ASN_UNIVERSAL ASN_APPLICATION ASN_CONTEXT ASN_PRIVATE | ||||
38 | ASN_PRIMITIVE ASN_CONSTRUCTOR ASN_LONG_LEN ASN_EXTENSION_ID ASN_BIT)], | ||||
39 | |||||
40 | tag => [qw(asn_tag asn_decode_tag2 asn_decode_tag asn_encode_tag asn_decode_length asn_encode_length)] | ||||
41 | ); | ||||
42 | |||||
43 | 1 | 22µs | @EXPORT_OK = map { @$_ } values %EXPORT_TAGS; | ||
44 | 1 | 2µs | $EXPORT_TAGS{all} = \@EXPORT_OK; | ||
45 | |||||
46 | 1 | 1µs | @opParts = qw( | ||
47 | cTAG cTYPE cVAR cLOOP cOPT cCHILD cDEFINE | ||||
48 | ); | ||||
49 | |||||
50 | 1 | 2µs | @opName = qw( | ||
51 | opUNKNOWN opBOOLEAN opINTEGER opBITSTR opSTRING opNULL opOBJID opREAL | ||||
52 | opSEQUENCE opSET opUTIME opGTIME opUTF8 opANY opCHOICE opROID opBCD | ||||
53 | ); | ||||
54 | |||||
55 | 1 | 10µs | foreach my $l (\@opParts, \@opName) { | ||
56 | 2 | 700ns | my $i = 0; | ||
57 | 2 | 3µs | foreach my $name (@$l) { | ||
58 | 24 | 8µs | my $j = $i++; | ||
59 | 3 | 93µs | 2 | 82µs | # spent 49µs (15+33) within Convert::ASN1::BEGIN@59 which was called:
# once (15µs+33µs) by Net::LDAP::BEGIN@12 at line 59 # spent 49µs making 1 call to Convert::ASN1::BEGIN@59
# spent 33µs making 1 call to strict::unimport |
60 | *{__PACKAGE__ . '::' . $name} = sub () { $j } | ||||
61 | 24 | 171µs | } | ||
62 | } | ||||
63 | 1 | 85µs | 1 | 271µs | } # spent 271µs making 1 call to Convert::ASN1::BEGIN@16 |
64 | |||||
65 | # spent 89µs within Convert::ASN1::_internal_syms which was called:
# once (89µs+0s) by Convert::ASN1::parser::BEGIN@16 at line 16 of Convert/ASN1/parser.pm | ||||
66 | 1 | 1µs | my $pkg = caller; | ||
67 | 3 | 1.93ms | 2 | 61µs | # spent 38µs (16+22) within Convert::ASN1::BEGIN@67 which was called:
# once (16µs+22µs) by Net::LDAP::BEGIN@12 at line 67 # spent 38µs making 1 call to Convert::ASN1::BEGIN@67
# spent 22µs making 1 call to strict::unimport |
68 | 1 | 12µs | for my $sub (@opParts,@opName,'dump_op') { | ||
69 | 25 | 84µs | *{$pkg . '::' . $sub} = \&{__PACKAGE__ . '::' . $sub}; | ||
70 | } | ||||
71 | } | ||||
72 | |||||
73 | sub ASN_BOOLEAN () { 0x01 } | ||||
74 | sub ASN_INTEGER () { 0x02 } | ||||
75 | sub ASN_BIT_STR () { 0x03 } | ||||
76 | sub ASN_OCTET_STR () { 0x04 } | ||||
77 | sub ASN_NULL () { 0x05 } | ||||
78 | sub ASN_OBJECT_ID () { 0x06 } | ||||
79 | sub ASN_REAL () { 0x09 } | ||||
80 | sub ASN_ENUMERATED () { 0x0A } | ||||
81 | sub ASN_RELATIVE_OID () { 0x0D } | ||||
82 | sub ASN_SEQUENCE () { 0x10 } | ||||
83 | sub ASN_SET () { 0x11 } | ||||
84 | sub ASN_PRINT_STR () { 0x13 } | ||||
85 | sub ASN_IA5_STR () { 0x16 } | ||||
86 | sub ASN_UTC_TIME () { 0x17 } | ||||
87 | sub ASN_GENERAL_TIME () { 0x18 } | ||||
88 | |||||
89 | sub ASN_UNIVERSAL () { 0x00 } | ||||
90 | sub ASN_APPLICATION () { 0x40 } | ||||
91 | sub ASN_CONTEXT () { 0x80 } | ||||
92 | sub ASN_PRIVATE () { 0xC0 } | ||||
93 | |||||
94 | sub ASN_PRIMITIVE () { 0x00 } | ||||
95 | sub ASN_CONSTRUCTOR () { 0x20 } | ||||
96 | |||||
97 | sub ASN_LONG_LEN () { 0x80 } | ||||
98 | sub ASN_EXTENSION_ID () { 0x1F } | ||||
99 | sub ASN_BIT () { 0x80 } | ||||
100 | |||||
101 | |||||
102 | # spent 52µs (21+31) within Convert::ASN1::new which was called:
# once (21µs+31µs) by Net::LDAP::Message::BEGIN@8 at line 8 of Net/LDAP/ASN.pm | ||||
103 | 1 | 2µs | my $pkg = shift; | ||
104 | 1 | 10µs | my $self = bless {}, $pkg; | ||
105 | |||||
106 | 1 | 4µs | 1 | 31µs | $self->configure(@_); # spent 31µs making 1 call to Convert::ASN1::configure |
107 | 1 | 4µs | $self; | ||
108 | } | ||||
109 | |||||
110 | |||||
111 | # spent 31µs (26+5) within Convert::ASN1::configure which was called:
# once (26µs+5µs) by Convert::ASN1::new at line 106 | ||||
112 | 1 | 600ns | my $self = shift; | ||
113 | 1 | 2µs | my %opt = @_; | ||
114 | |||||
115 | 1 | 5µs | $self->{options}{encoding} = uc($opt{encoding} || 'BER'); | ||
116 | |||||
117 | 1 | 18µs | 1 | 5µs | unless ($self->{options}{encoding} =~ /^[BD]ER$/) { # spent 5µs making 1 call to Convert::ASN1::CORE:match |
118 | require Carp; | ||||
119 | Carp::croak("Unsupported encoding format '$opt{encoding}'"); | ||||
120 | } | ||||
121 | |||||
122 | 1 | 6µs | for my $type (qw(encode decode)) { | ||
123 | 2 | 2µs | if (exists $opt{$type}) { | ||
124 | while(my($what,$value) = each %{$opt{$type}}) { | ||||
125 | $self->{options}{"${type}_${what}"} = $value; | ||||
126 | } | ||||
127 | } | ||||
128 | } | ||||
129 | } | ||||
130 | |||||
- - | |||||
133 | # spent 24µs within Convert::ASN1::find which was called 2 times, avg 12µs/call:
# 2 times (24µs+0s) by Net::LDAP::ASN::import at line 15 of Net/LDAP/ASN.pm, avg 12µs/call | ||||
134 | 2 | 1µs | my $self = shift; | ||
135 | 2 | 1µs | my $what = shift; | ||
136 | 2 | 3µs | return unless exists $self->{tree}{$what}; | ||
137 | 2 | 8µs | my %new = %$self; | ||
138 | 2 | 3µs | $new{script} = $new{tree}->{$what}; | ||
139 | 2 | 13µs | bless \%new, ref($self); | ||
140 | } | ||||
141 | |||||
142 | |||||
143 | # spent 103ms (34µs+103) within Convert::ASN1::prepare which was called:
# once (34µs+103ms) by Net::LDAP::Message::BEGIN@8 at line 22 of Net/LDAP/ASN.pm | ||||
144 | 1 | 800ns | my $self = shift; | ||
145 | 1 | 4µs | my $asn = shift; | ||
146 | |||||
147 | 1 | 1µs | $self = $self->new unless ref($self); | ||
148 | 1 | 400ns | my $tree; | ||
149 | 1 | 2µs | if( ref($asn) eq 'GLOB' ){ | ||
150 | local $/ = undef; | ||||
151 | my $txt = <$asn>; | ||||
152 | $tree = Convert::ASN1::parser::parse($txt); | ||||
153 | } else { | ||||
154 | 1 | 4µs | 1 | 103ms | $tree = Convert::ASN1::parser::parse($asn); # spent 103ms making 1 call to Convert::ASN1::parser::parse |
155 | } | ||||
156 | |||||
157 | 1 | 900ns | unless ($tree) { | ||
158 | $self->{error} = $@; | ||||
159 | return; | ||||
160 | ### If $self has been set to a new object, not returning | ||||
161 | ### this object here will destroy the object, so the caller | ||||
162 | ### won't be able to get at the error. | ||||
163 | } | ||||
164 | |||||
165 | 1 | 6µs | 1 | 3µs | $self->{tree} = _pack_struct($tree); # spent 3µs making 1 call to Convert::ASN1::_pack_struct |
166 | 1 | 7µs | $self->{script} = (values %$tree)[0]; | ||
167 | 1 | 6µs | $self; | ||
168 | } | ||||
169 | |||||
170 | sub prepare_file { | ||||
171 | my $self = shift; | ||||
172 | my $asnp = shift; | ||||
173 | |||||
174 | local *ASN; | ||||
175 | open( ASN, $asnp ) | ||||
176 | or do{ $self->{error} = $@; return; }; | ||||
177 | my $ret = $self->prepare( \*ASN ); | ||||
178 | close( ASN ); | ||||
179 | $ret; | ||||
180 | } | ||||
181 | |||||
182 | sub registeroid { | ||||
183 | my $self = shift; | ||||
184 | my $oid = shift; | ||||
185 | my $handler = shift; | ||||
186 | |||||
187 | $self->{options}{oidtable}{$oid}=$handler; | ||||
188 | $self->{oidtable}{$oid}=$handler; | ||||
189 | } | ||||
190 | |||||
191 | sub registertype { | ||||
192 | my $self = shift; | ||||
193 | my $def = shift; | ||||
194 | my $type = shift; | ||||
195 | my $handler = shift; | ||||
196 | |||||
197 | $self->{options}{handlers}{$def}{$type}=$handler; | ||||
198 | } | ||||
199 | |||||
200 | # In XS the will convert the tree between perl and C structs | ||||
201 | |||||
202 | 1 | 5µs | # spent 3µs within Convert::ASN1::_pack_struct which was called:
# once (3µs+0s) by Convert::ASN1::prepare at line 165 | ||
203 | sub _unpack_struct { $_[0] } | ||||
204 | |||||
205 | ## | ||||
206 | ## Encoding | ||||
207 | ## | ||||
208 | |||||
209 | sub encode { | ||||
210 | my $self = shift; | ||||
211 | my $stash = @_ == 1 ? shift : { @_ }; | ||||
212 | my $buf = ''; | ||||
213 | local $SIG{__DIE__}; | ||||
214 | eval { _encode($self->{options}, $self->{script}, $stash, [], $buf) } | ||||
215 | or do { $self->{error} = $@; undef } | ||||
216 | } | ||||
217 | |||||
- - | |||||
220 | # Encode tag value for encoding. | ||||
221 | # We assume that the tag has been correctly generated with asn_tag() | ||||
222 | |||||
223 | # spent 216µs within Convert::ASN1::asn_encode_tag which was called 105 times, avg 2µs/call:
# 45 times (106µs+0s) by Convert::ASN1::parser::compile_one at line 679 of Convert/ASN1/parser.pm, avg 2µs/call
# 31 times (42µs+0s) by Convert::ASN1::BEGIN@415 at line 21 of Convert/ASN1/parser.pm, avg 1µs/call
# 29 times (69µs+0s) by Convert::ASN1::parser::compile_one at line 664 of Convert/ASN1/parser.pm, avg 2µs/call | ||||
224 | 105 | 314µs | $_[0] >> 8 | ||
225 | ? $_[0] & 0x8000 | ||||
226 | ? $_[0] & 0x800000 | ||||
227 | ? pack("V",$_[0]) | ||||
228 | : substr(pack("V",$_[0]),0,3) | ||||
229 | : pack("v", $_[0]) | ||||
230 | : chr($_[0]); | ||||
231 | } | ||||
232 | |||||
233 | |||||
234 | # Encode a length. If < 0x80 then encode as a byte. Otherwise encode | ||||
235 | # 0x80 | num_bytes followed by the bytes for the number. top end | ||||
236 | # bytes of all zeros are not encoded | ||||
237 | |||||
238 | sub asn_encode_length { | ||||
239 | |||||
240 | if($_[0] >> 7) { | ||||
241 | my $lenlen = &num_length; | ||||
242 | |||||
243 | return pack("Ca*", $lenlen | 0x80, substr(pack("N",$_[0]), -$lenlen)); | ||||
244 | } | ||||
245 | |||||
246 | return pack("C", $_[0]); | ||||
247 | } | ||||
248 | |||||
249 | |||||
250 | ## | ||||
251 | ## Decoding | ||||
252 | ## | ||||
253 | |||||
254 | sub decode { | ||||
255 | my $self = shift; | ||||
256 | |||||
257 | local $SIG{__DIE__}; | ||||
258 | my $ret = eval { | ||||
259 | my (%stash, $result); | ||||
260 | my $script = $self->{script}; | ||||
261 | my $stash = (1 == @$script && !$self->{script}[0][cVAR]) ? \$result : ($result=\%stash); | ||||
262 | |||||
263 | _decode( | ||||
264 | $self->{options}, | ||||
265 | $script, | ||||
266 | $stash, | ||||
267 | 0, | ||||
268 | length $_[0], | ||||
269 | undef, | ||||
270 | {}, | ||||
271 | $_[0]); | ||||
272 | |||||
273 | $result; | ||||
274 | }; | ||||
275 | if ($@) { | ||||
276 | $self->{'error'} = $@; | ||||
277 | return undef; | ||||
278 | } | ||||
279 | $ret; | ||||
280 | } | ||||
281 | |||||
282 | |||||
283 | sub asn_decode_length { | ||||
284 | return unless length $_[0]; | ||||
285 | |||||
286 | my $len = ord substr($_[0],0,1); | ||||
287 | |||||
288 | if($len & 0x80) { | ||||
289 | $len &= 0x7f or return (1,-1); | ||||
290 | |||||
291 | return if $len >= length $_[0]; | ||||
292 | |||||
293 | return (1+$len, unpack("N", "\0" x (4 - $len) . substr($_[0],1,$len))); | ||||
294 | } | ||||
295 | return (1, $len); | ||||
296 | } | ||||
297 | |||||
298 | |||||
299 | sub asn_decode_tag { | ||||
300 | return unless length $_[0]; | ||||
301 | |||||
302 | my $tag = ord $_[0]; | ||||
303 | my $n = 1; | ||||
304 | |||||
305 | if(($tag & 0x1f) == 0x1f) { | ||||
306 | my $b; | ||||
307 | do { | ||||
308 | return if $n >= length $_[0]; | ||||
309 | $b = ord substr($_[0],$n,1); | ||||
310 | $tag |= $b << (8 * $n++); | ||||
311 | } while($b & 0x80); | ||||
312 | } | ||||
313 | ($n, $tag); | ||||
314 | } | ||||
315 | |||||
316 | |||||
317 | sub asn_decode_tag2 { | ||||
318 | return unless length $_[0]; | ||||
319 | |||||
320 | my $tag = ord $_[0]; | ||||
321 | my $num = $tag & 0x1f; | ||||
322 | my $len = 1; | ||||
323 | |||||
324 | if($num == 0x1f) { | ||||
325 | $num = 0; | ||||
326 | my $b; | ||||
327 | do { | ||||
328 | return if $len >= length $_[0]; | ||||
329 | $b = ord substr($_[0],$len++,1); | ||||
330 | $num = ($num << 7) + ($b & 0x7f); | ||||
331 | } while($b & 0x80); | ||||
332 | } | ||||
333 | ($len, $tag, $num); | ||||
334 | } | ||||
335 | |||||
336 | |||||
337 | ## | ||||
338 | ## Utilities | ||||
339 | ## | ||||
340 | |||||
341 | # How many bytes are needed to encode a number | ||||
342 | |||||
343 | sub num_length { | ||||
344 | $_[0] >> 8 | ||||
345 | ? $_[0] >> 16 | ||||
346 | ? $_[0] >> 24 | ||||
347 | ? 4 | ||||
348 | : 3 | ||||
349 | : 2 | ||||
350 | : 1 | ||||
351 | } | ||||
352 | |||||
353 | # Convert from a bigint to an octet string | ||||
354 | |||||
355 | sub i2osp { | ||||
356 | my($num, $biclass) = @_; | ||||
357 | eval "use $biclass"; | ||||
358 | $num = $biclass->new($num); | ||||
359 | my $neg = $num < 0 | ||||
360 | and $num = abs($num+1); | ||||
361 | my $base = $biclass->new(256); | ||||
362 | my $result = ''; | ||||
363 | while($num != 0) { | ||||
364 | my $r = $num % $base; | ||||
365 | $num = ($num-$r) / $base; | ||||
366 | $result .= chr($r); | ||||
367 | } | ||||
368 | $result ^= chr(255) x length($result) if $neg; | ||||
369 | return scalar reverse $result; | ||||
370 | } | ||||
371 | |||||
372 | # Convert from an octet string to a bigint | ||||
373 | |||||
374 | sub os2ip { | ||||
375 | my($os, $biclass) = @_; | ||||
376 | eval "require $biclass"; | ||||
377 | my $base = $biclass->new(256); | ||||
378 | my $result = $biclass->new(0); | ||||
379 | my $neg = ord($os) >= 0x80 | ||||
380 | and $os ^= chr(255) x length($os); | ||||
381 | for (unpack("C*",$os)) { | ||||
382 | $result = ($result * $base) + $_; | ||||
383 | } | ||||
384 | return $neg ? ($result + 1) * -1 : $result; | ||||
385 | } | ||||
386 | |||||
387 | # Given a class and a tag, calculate an integer which when encoded | ||||
388 | # will become the tag. This means that the class bits are always | ||||
389 | # in the bottom byte, so are the tag bits if tag < 30. Otherwise | ||||
390 | # the tag is in the upper 3 bytes. The upper bytes are encoded | ||||
391 | # with bit8 representing that there is another byte. This | ||||
392 | # means the max tag we can do is 0x1fffff | ||||
393 | |||||
394 | # spent 638µs within Convert::ASN1::asn_tag which was called 74 times, avg 9µs/call:
# 74 times (638µs+0s) by Convert::ASN1::parser::yylex at line 881 of Convert/ASN1/parser.pm, avg 9µs/call | ||||
395 | 74 | 98µs | my($class,$value) = @_; | ||
396 | |||||
397 | 74 | 60µs | die sprintf "Bad tag class 0x%x",$class | ||
398 | if $class & ~0xe0; | ||||
399 | |||||
400 | 74 | 486µs | unless ($value & ~0x1f or $value == 0x1f) { | ||
401 | return (($class & 0xe0) | $value); | ||||
402 | } | ||||
403 | |||||
404 | die sprintf "Tag value 0x%08x too big\n",$value | ||||
405 | if $value & 0xffe00000; | ||||
406 | |||||
407 | $class = ($class | 0x1f) & 0xff; | ||||
408 | |||||
409 | my @t = ($value & 0x7f); | ||||
410 | unshift @t, (0x80 | ($value & 0x7f)) while $value >>= 7; | ||||
411 | unpack("V",pack("C4",$class,@t,0,0)); | ||||
412 | } | ||||
413 | |||||
414 | |||||
415 | # spent 13.8ms (11.8+1.98) within Convert::ASN1::BEGIN@415 which was called:
# once (11.8ms+1.98ms) by Net::LDAP::BEGIN@12 at line 425 | ||||
416 | # When we have XS &_encode will be defined by the XS code | ||||
417 | # so will all the subs in these required packages | ||||
418 | 1 | 2µs | unless (defined &_encode) { | ||
419 | 1 | 107µs | require Convert::ASN1::_decode; | ||
420 | 1 | 119µs | require Convert::ASN1::_encode; | ||
421 | 1 | 85µs | require Convert::ASN1::IO; | ||
422 | } | ||||
423 | |||||
424 | 1 | 90µs | require Convert::ASN1::parser; | ||
425 | 1 | 196µs | 1 | 13.8ms | } # spent 13.8ms making 1 call to Convert::ASN1::BEGIN@415 |
426 | |||||
427 | sub AUTOLOAD { | ||||
428 | require Convert::ASN1::Debug if $AUTOLOAD =~ /dump/; | ||||
429 | goto &{$AUTOLOAD} if defined &{$AUTOLOAD}; | ||||
430 | require Carp; | ||||
431 | my $pkg = ref($_[0]) || ($_[0] =~ /^[\w\d]+(?:::[\w\d]+)*$/)[0]; | ||||
432 | if ($pkg and UNIVERSAL::isa($pkg, __PACKAGE__)) { # guess it was a method call | ||||
433 | $AUTOLOAD =~ s/.*:://; | ||||
434 | Carp::croak(sprintf q{Can't locate object method "%s" via package "%s"},$AUTOLOAD,$pkg); | ||||
435 | } | ||||
436 | else { | ||||
437 | Carp::croak(sprintf q{Undefined subroutine &%s called}, $AUTOLOAD); | ||||
438 | } | ||||
439 | } | ||||
440 | |||||
441 | sub DESTROY {} | ||||
442 | |||||
443 | sub error { $_[0]->{error} } | ||||
444 | 1 | 3µs | 1; | ||
# spent 5µs within Convert::ASN1::CORE:match which was called:
# once (5µs+0s) by Convert::ASN1::configure at line 117 |