line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
1
|
|
|
1
|
|
585
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
29
|
|
2
|
1
|
|
|
1
|
|
5
|
use warnings FATAL => 'all'; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
59
|
|
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
package MarpaX::ESLIF::URI::tel; |
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
# ABSTRACT: URI::tel syntax as per RFC3966, RFC4694, RFC4715, RFC4759, RFC4904 |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our $AUTHORITY = 'cpan:JDDPAUSE'; # AUTHORITY |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
our $VERSION = '0.006'; # VERSION |
11
|
|
|
|
|
|
|
|
12
|
1
|
|
|
1
|
|
7
|
use Carp qw/croak/; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
57
|
|
13
|
1
|
|
|
1
|
|
6
|
use Class::Tiny::Antlers; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
8
|
|
14
|
1
|
|
|
1
|
|
153
|
use MarpaX::ESLIF; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
1699
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
extends 'MarpaX::ESLIF::URI::_generic'; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
has '_number' => (is => 'rwp'); |
19
|
|
|
|
|
|
|
has '_is_global' => (is => 'rwp'); |
20
|
|
|
|
|
|
|
has '_is_local' => (is => 'rwp'); |
21
|
|
|
|
|
|
|
has '_ext' => (is => 'rwp'); |
22
|
|
|
|
|
|
|
has '_isub' => (is => 'rwp'); |
23
|
|
|
|
|
|
|
has '_isub_encoding' => (is => 'rwp'); |
24
|
|
|
|
|
|
|
has '_tgrp' => (is => 'rwp'); |
25
|
|
|
|
|
|
|
has '_trunk_context' => (is => 'rwp'); |
26
|
|
|
|
|
|
|
has '_phone_context' => (is => 'rwp'); |
27
|
|
|
|
|
|
|
has '_rn' => (is => 'rwp'); |
28
|
|
|
|
|
|
|
has '_rn_context' => (is => 'rwp'); |
29
|
|
|
|
|
|
|
has '_cic' => (is => 'rwp'); |
30
|
|
|
|
|
|
|
has '_cic_context' => (is => 'rwp'); |
31
|
|
|
|
|
|
|
has '_has_npdi' => (is => 'rwp'); |
32
|
|
|
|
|
|
|
has '_has_enumdi' => (is => 'rwp'); |
33
|
|
|
|
|
|
|
has '_parameters' => (is => 'rwp', default => sub { { origin => [], decoded => [], normalized => [] } }); |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# |
36
|
|
|
|
|
|
|
# Constants |
37
|
|
|
|
|
|
|
# |
38
|
|
|
|
|
|
|
my $BNF = do { local $/; <DATA> }; |
39
|
|
|
|
|
|
|
my $GRAMMAR = MarpaX::ESLIF::Grammar->new(__PACKAGE__->eslif, __PACKAGE__->bnf); |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
sub bnf { |
43
|
1
|
|
|
1
|
1
|
3
|
my ($class) = @_; |
44
|
|
|
|
|
|
|
|
45
|
1
|
|
|
|
|
3
|
join("\n", $BNF, MarpaX::ESLIF::URI::_generic->bnf) |
46
|
|
|
|
|
|
|
}; |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
sub grammar { |
50
|
8
|
|
|
8
|
1
|
17
|
my ($class) = @_; |
51
|
|
|
|
|
|
|
|
52
|
8
|
|
|
|
|
394
|
return $GRAMMAR; |
53
|
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
sub number { |
57
|
24
|
|
|
24
|
1
|
10291
|
my ($self, $type) = @_; |
58
|
|
|
|
|
|
|
|
59
|
24
|
|
|
|
|
65
|
return $self->_generic_getter('_number', $type) |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
sub is_global { |
64
|
8
|
|
|
8
|
1
|
2976
|
my ($self) = @_; |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
return $self->{_is_global} |
67
|
8
|
|
|
|
|
21
|
} |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
sub is_local { |
71
|
8
|
|
|
8
|
1
|
3372
|
my ($self) = @_; |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
return $self->{_is_local} |
74
|
8
|
|
|
|
|
20
|
} |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub ext { |
78
|
0
|
|
|
0
|
1
|
0
|
my ($self, $type) = @_; |
79
|
|
|
|
|
|
|
|
80
|
0
|
|
|
|
|
0
|
return $self->_generic_getter('_ext', $type) |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
sub isub { |
85
|
0
|
|
|
0
|
1
|
0
|
my ($self, $type) = @_; |
86
|
|
|
|
|
|
|
|
87
|
0
|
|
|
|
|
0
|
return $self->_generic_getter('_isub', $type) |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
sub isub_encoding { |
92
|
3
|
|
|
3
|
1
|
1239
|
my ($self, $type) = @_; |
93
|
|
|
|
|
|
|
|
94
|
3
|
|
|
|
|
10
|
return $self->_generic_getter('_isub_encoding', $type) |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
sub tgrp { |
99
|
0
|
|
|
0
|
1
|
0
|
my ($self, $type) = @_; |
100
|
|
|
|
|
|
|
|
101
|
0
|
|
|
|
|
0
|
return $self->_generic_getter('_tgrp', $type) |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
sub trunk_context { |
106
|
0
|
|
|
0
|
1
|
0
|
my ($self, $type) = @_; |
107
|
|
|
|
|
|
|
|
108
|
0
|
|
|
|
|
0
|
return $self->_generic_getter('_trunk_context', $type) |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
sub phone_context { |
113
|
6
|
|
|
6
|
1
|
4748
|
my ($self, $type) = @_; |
114
|
|
|
|
|
|
|
|
115
|
6
|
|
|
|
|
334
|
return $self->_generic_getter('_phone_context', $type) |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
sub rn { |
120
|
3
|
|
|
3
|
1
|
2368
|
my ($self, $type) = @_; |
121
|
|
|
|
|
|
|
|
122
|
3
|
|
|
|
|
9
|
return $self->_generic_getter('_rn', $type) |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
sub rn_context { |
128
|
0
|
|
|
0
|
1
|
0
|
my ($self, $type) = @_; |
129
|
|
|
|
|
|
|
|
130
|
0
|
|
|
|
|
0
|
return $self->_generic_getter('_rn_context', $type) |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
sub cic { |
136
|
3
|
|
|
3
|
1
|
1369
|
my ($self, $type) = @_; |
137
|
|
|
|
|
|
|
|
138
|
3
|
|
|
|
|
9
|
return $self->_generic_getter('_cic', $type) |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
sub cic_context { |
143
|
0
|
|
|
0
|
1
|
0
|
my ($self, $type) = @_; |
144
|
|
|
|
|
|
|
|
145
|
0
|
|
|
|
|
0
|
return $self->_generic_getter('_cic_context', $type) |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
sub has_npdi { |
150
|
7
|
|
|
7
|
1
|
2434
|
my ($self) = @_; |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
return $self->{_has_npdi} |
153
|
7
|
|
|
|
|
16
|
} |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
sub has_enumdi { |
157
|
7
|
|
|
7
|
1
|
3243
|
my ($self) = @_; |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
return $self->{_has_enumdi} |
160
|
7
|
|
|
|
|
16
|
} |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
sub parameters { |
164
|
21
|
|
|
21
|
1
|
22023
|
my ($self, $type) = @_; |
165
|
|
|
|
|
|
|
|
166
|
21
|
|
|
|
|
65
|
return $self->_generic_getter('_parameters', $type) |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
# ------------------------ |
170
|
|
|
|
|
|
|
# Specific grammar actions |
171
|
|
|
|
|
|
|
# ------------------------ |
172
|
|
|
|
|
|
|
sub __number { |
173
|
11
|
|
|
11
|
|
23
|
my ($self, @args) = @_; |
174
|
|
|
|
|
|
|
|
175
|
11
|
|
|
|
|
30
|
my $rc = $self->__concat(@args); |
176
|
|
|
|
|
|
|
# |
177
|
|
|
|
|
|
|
# Normalizer number is without the visual separators |
178
|
|
|
|
|
|
|
# |
179
|
11
|
|
|
|
|
58
|
$rc->{normalized} =~ s/[-.()]//g; |
180
|
|
|
|
|
|
|
|
181
|
11
|
|
|
|
|
92
|
return $rc |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
sub __global { |
185
|
6
|
|
|
6
|
|
15
|
my ($self, $global_number_digits, @rest) = @_; |
186
|
|
|
|
|
|
|
|
187
|
6
|
|
|
|
|
17
|
$self->{_is_global} = 1; |
188
|
6
|
|
|
|
|
12
|
$self->{_number} = $global_number_digits; |
189
|
|
|
|
|
|
|
|
190
|
6
|
|
|
|
|
17
|
return $self->__concat($global_number_digits, @rest) |
191
|
|
|
|
|
|
|
} |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
sub __local { |
194
|
2
|
|
|
2
|
|
4
|
my ($self, $local_number_digits, @rest) = @_; |
195
|
|
|
|
|
|
|
|
196
|
2
|
|
|
|
|
8
|
$self->{_is_local} = 1; |
197
|
2
|
|
|
|
|
6
|
$self->{_number} = $local_number_digits; |
198
|
|
|
|
|
|
|
|
199
|
2
|
|
|
|
|
18
|
return $self->__concat($local_number_digits, @rest) |
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
sub __pname { |
203
|
0
|
|
|
0
|
|
0
|
my ($self, @args) = @_; |
204
|
|
|
|
|
|
|
# |
205
|
|
|
|
|
|
|
# Normalized <pname> is case-insensitive. |
206
|
|
|
|
|
|
|
# |
207
|
0
|
|
|
|
|
0
|
my $rc = $self->__concat(@args); |
208
|
|
|
|
|
|
|
|
209
|
0
|
|
|
|
|
0
|
return $rc |
210
|
|
|
|
|
|
|
} |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
sub __parameter_cmp { |
213
|
0
|
|
|
0
|
|
0
|
my ($parametera, $parameterb) = @_; |
214
|
|
|
|
|
|
|
|
215
|
0
|
|
|
|
|
0
|
my $keya = $parametera->{key}; |
216
|
0
|
|
|
|
|
0
|
my $keyb = $parameterb->{key}; |
217
|
|
|
|
|
|
|
|
218
|
0
|
0
|
0
|
|
|
0
|
if (($keya eq 'ext') or ($keya eq 'isub')) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
219
|
0
|
0
|
0
|
|
|
0
|
if (($keyb eq 'ext') or ($keyb eq 'isub')) { |
220
|
|
|
|
|
|
|
# |
221
|
|
|
|
|
|
|
# ext will naturally come before isub |
222
|
|
|
|
|
|
|
# |
223
|
0
|
|
|
|
|
0
|
return $keya cmp $keyb |
224
|
|
|
|
|
|
|
} else { |
225
|
|
|
|
|
|
|
# |
226
|
|
|
|
|
|
|
# ext or isub always comes first |
227
|
|
|
|
|
|
|
# |
228
|
0
|
|
|
|
|
0
|
return 1 |
229
|
|
|
|
|
|
|
} |
230
|
|
|
|
|
|
|
} elsif ($keya eq 'phone-context') { |
231
|
|
|
|
|
|
|
# |
232
|
|
|
|
|
|
|
# phone-context always appear after ext or isub, if any, and before any other parameter |
233
|
|
|
|
|
|
|
# |
234
|
0
|
0
|
0
|
|
|
0
|
if (($keyb eq 'ext') or ($keyb eq 'isub')) { |
235
|
0
|
|
|
|
|
0
|
return -1 |
236
|
|
|
|
|
|
|
} else { |
237
|
0
|
|
|
|
|
0
|
return 1 |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
} elsif ($keyb eq 'phone-context') { |
240
|
|
|
|
|
|
|
# |
241
|
|
|
|
|
|
|
# phone-context always appear after ext or isub, if any, and before any other parameter |
242
|
|
|
|
|
|
|
# |
243
|
0
|
0
|
0
|
|
|
0
|
if (($keya eq 'ext') or ($keya eq 'isub')) { |
244
|
0
|
|
|
|
|
0
|
return 1 |
245
|
|
|
|
|
|
|
} else { |
246
|
0
|
|
|
|
|
0
|
return -1 |
247
|
|
|
|
|
|
|
} |
248
|
|
|
|
|
|
|
} else { |
249
|
0
|
|
|
|
|
0
|
return $keya cmp $keyb |
250
|
|
|
|
|
|
|
} |
251
|
|
|
|
|
|
|
} |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
sub __parameter { |
254
|
10
|
|
|
10
|
|
22
|
my ($self, $semicolumn, $pname, $equal, $pvalue) = @_; # $equal and $pvalue may be undef |
255
|
|
|
|
|
|
|
# |
256
|
|
|
|
|
|
|
# Each parameter name ("pname"), the ISDN subaddress, the 'extension', |
257
|
|
|
|
|
|
|
# and the 'context' MUST NOT appear more than once. The 'isdn- |
258
|
|
|
|
|
|
|
# subaddress' or 'extension' MUST appear first, if present, followed by |
259
|
|
|
|
|
|
|
# the 'context' parameter, if present, followed by any other parameters |
260
|
|
|
|
|
|
|
# in lexicographical order. |
261
|
|
|
|
|
|
|
# |
262
|
10
|
|
|
|
|
31
|
my $concat = $self->__concat($semicolumn, $pname, $equal, $pvalue); |
263
|
|
|
|
|
|
|
|
264
|
10
|
|
|
|
|
20
|
foreach my $type (qw/normalized origin decoded/) { # C.f. __add_parameter for normalization |
265
|
30
|
|
|
|
|
166
|
my $key = $pname->{$type}; |
266
|
30
|
100
|
|
|
|
60
|
my $value = defined($pvalue) ? $pvalue->{$type} : undef; |
267
|
|
|
|
|
|
|
# |
268
|
|
|
|
|
|
|
# We compare using the normalized type |
269
|
|
|
|
|
|
|
# |
270
|
30
|
100
|
|
|
|
57
|
if ($type eq 'normalized') { |
271
|
10
|
|
|
|
|
17
|
my $keyNotNormalized = $pname->{origin}; |
272
|
|
|
|
|
|
|
# |
273
|
|
|
|
|
|
|
# A parameter must not appear more than once - this makes sure that |
274
|
|
|
|
|
|
|
# reserved keywords coming from unwanted rule par ::= parameter are |
275
|
|
|
|
|
|
|
# catched, e.g. 'Ext' alone |
276
|
|
|
|
|
|
|
# |
277
|
10
|
50
|
|
|
|
15
|
if (grep {$_ eq $key} map { $_->{key} } @{$self->_parameters->{$type}}) { |
|
4
|
100
|
|
|
|
10
|
|
|
4
|
|
|
|
|
28
|
|
|
10
|
|
|
|
|
172
|
|
278
|
0
|
|
|
|
|
0
|
croak "Parameter '$keyNotNormalized' already exists" |
279
|
10
|
|
|
|
|
169
|
} elsif (@{$self->_parameters->{$type}}) { |
280
|
3
|
50
|
33
|
|
|
32
|
if (($key eq 'ext') || ($key eq 'isub')) { |
|
|
50
|
|
|
|
|
|
281
|
|
|
|
|
|
|
# |
282
|
|
|
|
|
|
|
# isub or ext must appear first |
283
|
|
|
|
|
|
|
# |
284
|
0
|
|
|
|
|
0
|
my $previouskey = $self->_parameters->{$type}->[-1]->{key}; |
285
|
0
|
0
|
0
|
|
|
0
|
if (($previouskey ne 'ext') && ($previouskey ne 'isub')) { |
286
|
0
|
|
|
|
|
0
|
my $previouskeyNotNormalized = $self->_parameters->{origin}->[-1]->{key}; |
287
|
0
|
|
|
|
|
0
|
croak "Parameter '$keyNotNormalized' must appear before '$previouskeyNotNormalized'" |
288
|
|
|
|
|
|
|
} |
289
|
|
|
|
|
|
|
} elsif ($key eq 'phone-context') { |
290
|
|
|
|
|
|
|
# |
291
|
|
|
|
|
|
|
# context parameter must be after isub or ext if present |
292
|
|
|
|
|
|
|
# |
293
|
0
|
|
|
|
|
0
|
my $max = -1; |
294
|
0
|
|
|
|
|
0
|
my $firstkey = $self->_parameters->{$type}->[0]->{key}; |
295
|
0
|
0
|
0
|
|
|
0
|
if (($firstkey eq 'ext') || ($firstkey eq 'isub')) { |
296
|
0
|
0
|
|
|
|
0
|
if ($#{$self->_parameters->{$type}} > 0) { |
|
0
|
|
|
|
|
0
|
|
297
|
0
|
|
|
|
|
0
|
my $secondkey = $self->_parameters->{$type}->[1]->{key}; |
298
|
0
|
0
|
0
|
|
|
0
|
if (($secondkey eq 'ext') || ($secondkey eq 'isub')) { |
299
|
0
|
|
|
|
|
0
|
$max = 1; |
300
|
|
|
|
|
|
|
} else { |
301
|
0
|
|
|
|
|
0
|
$max = 0; |
302
|
|
|
|
|
|
|
} |
303
|
|
|
|
|
|
|
} |
304
|
|
|
|
|
|
|
} |
305
|
0
|
0
|
0
|
|
|
0
|
if (($max >= 0) && ($#{$self->_parameters->{$type}} != $max)) { |
|
0
|
|
|
|
|
0
|
|
306
|
0
|
|
|
|
|
0
|
my $targetkeyNotNormalized = $self->_parameters->{origin}->[$max]->{key}; |
307
|
0
|
|
|
|
|
0
|
croak "Parameter '$keyNotNormalized' must appear after '$targetkeyNotNormalized'" |
308
|
|
|
|
|
|
|
} |
309
|
|
|
|
|
|
|
} else { |
310
|
|
|
|
|
|
|
# |
311
|
|
|
|
|
|
|
# Any other must be in lexicographical order |
312
|
|
|
|
|
|
|
# |
313
|
3
|
|
|
|
|
40
|
my $previouskey = $self->_parameters->{$type}->[-1]->{key}; |
314
|
3
|
100
|
33
|
|
|
30
|
if (($previouskey ne 'ext') && ($previouskey ne 'isub') && ($previouskey ne 'phone-context')) { |
|
|
|
66
|
|
|
|
|
315
|
2
|
50
|
|
|
|
10
|
if (($previouskey cmp $key) >= 0) { |
316
|
0
|
|
|
|
|
0
|
croak "Parameter '$keyNotNormalized' must appear before previous parameter '$previouskey'" |
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
} |
319
|
|
|
|
|
|
|
} |
320
|
|
|
|
|
|
|
} |
321
|
|
|
|
|
|
|
} |
322
|
|
|
|
|
|
|
|
323
|
30
|
|
|
|
|
74
|
push(@{$self->_parameters->{$type}}, { key => $key, value => $value }); |
|
30
|
|
|
|
|
403
|
|
324
|
|
|
|
|
|
|
} |
325
|
|
|
|
|
|
|
|
326
|
10
|
|
|
|
|
158
|
return $concat |
327
|
|
|
|
|
|
|
} |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
my $semicolumn = { normalized => ';', origin => ';', decoded => ';' }; |
330
|
|
|
|
|
|
|
my $equal = { normalized => '=', origin => '=', decoded => '=' }; |
331
|
|
|
|
|
|
|
sub __add_parameter { |
332
|
10
|
|
|
10
|
|
24
|
my ($self, $name, $pvalue) = @_; |
333
|
|
|
|
|
|
|
|
334
|
10
|
|
|
|
|
14
|
my %pname; |
335
|
10
|
|
|
|
|
21
|
foreach my $type (qw/normalized origin decoded/) { |
336
|
30
|
|
|
|
|
60
|
$pname{$type} = $name->{$type}; |
337
|
30
|
50
|
|
|
|
84
|
substr($pname{$type}, 0, 1, '') if substr($pname{$type}, 0, 1) eq ';'; |
338
|
30
|
100
|
|
|
|
69
|
substr($pname{$type}, -1, 1, '') if substr($pname{$type}, -1, 1) eq '='; |
339
|
|
|
|
|
|
|
} |
340
|
|
|
|
|
|
|
|
341
|
10
|
|
|
|
|
24
|
$pname{normalized} = lc($pname{normalized}); |
342
|
10
|
100
|
|
|
|
24
|
if (defined($pvalue)) { |
343
|
|
|
|
|
|
|
$pvalue->{normalized} = lc($pvalue->{normalized}) |
344
|
7
|
|
|
|
|
14
|
} |
345
|
|
|
|
|
|
|
|
346
|
10
|
|
|
|
|
32
|
return $self->__parameter($semicolumn, \%pname, $equal, $pvalue) |
347
|
|
|
|
|
|
|
} |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
sub __ext { |
350
|
0
|
|
|
0
|
|
0
|
my ($self, $ext, $pvalue) = @_; |
351
|
|
|
|
|
|
|
|
352
|
0
|
|
|
|
|
0
|
return $self->__add_parameter($ext, $self->{_ext} = $pvalue) |
353
|
|
|
|
|
|
|
} |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
sub __isub { |
356
|
0
|
|
|
0
|
|
0
|
my ($self, $isub, $pvalue) = @_; |
357
|
|
|
|
|
|
|
|
358
|
0
|
|
|
|
|
0
|
return $self->__add_parameter($isub, $self->{_isub} = $pvalue) |
359
|
|
|
|
|
|
|
} |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
sub __tgrp { |
362
|
1
|
|
|
1
|
|
3
|
my ($self, $tgrp, $pvalue) = @_; |
363
|
|
|
|
|
|
|
|
364
|
1
|
|
|
|
|
5
|
return $self->__add_parameter($tgrp, $self->{_tgrp} = $pvalue) |
365
|
|
|
|
|
|
|
} |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
sub __trunk_context { |
368
|
1
|
|
|
1
|
|
3
|
my ($self, $trunk_context, $pvalue) = @_; |
369
|
|
|
|
|
|
|
|
370
|
1
|
|
|
|
|
4
|
return $self->__add_parameter($trunk_context, $self->{_trunk_context} = $pvalue) |
371
|
|
|
|
|
|
|
} |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
sub __phone_context { |
374
|
2
|
|
|
2
|
|
5
|
my ($self, $phone_context, $pvalue) = @_; |
375
|
|
|
|
|
|
|
|
376
|
2
|
|
|
|
|
8
|
return $self->__add_parameter($phone_context, $self->{_phone_context} = $pvalue) |
377
|
|
|
|
|
|
|
} |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
sub __rn { |
380
|
1
|
|
|
1
|
|
4
|
my ($self, $rn, $pvalue) = @_; |
381
|
|
|
|
|
|
|
|
382
|
1
|
|
|
|
|
5
|
return $self->__add_parameter($rn, $self->{_rn} = $pvalue) |
383
|
|
|
|
|
|
|
} |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
sub __rn_context { |
386
|
0
|
|
|
0
|
|
0
|
my ($self, $rn_context, $pvalue) = @_; |
387
|
|
|
|
|
|
|
|
388
|
0
|
|
|
|
|
0
|
return $self->__add_parameter($rn_context, $self->{_rn_context} = $pvalue) |
389
|
|
|
|
|
|
|
} |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
sub __npdi { |
392
|
2
|
|
|
2
|
|
5
|
my ($self, $npdi) = @_; |
393
|
|
|
|
|
|
|
|
394
|
2
|
|
|
|
|
5
|
$self->{_has_npdi} = 1; |
395
|
|
|
|
|
|
|
|
396
|
2
|
|
|
|
|
8
|
return $self->__add_parameter($npdi) |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
sub __cic { |
400
|
1
|
|
|
1
|
|
3
|
my ($self, $cic, $pvalue) = @_; |
401
|
|
|
|
|
|
|
|
402
|
1
|
|
|
|
|
4
|
return $self->__add_parameter($cic, $self->{_cic} = $pvalue) |
403
|
|
|
|
|
|
|
} |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
sub __cic_context { |
406
|
0
|
|
|
0
|
|
0
|
my ($self, $cic_context, $pvalue) = @_; |
407
|
|
|
|
|
|
|
|
408
|
0
|
|
|
|
|
0
|
return $self->__add_parameter($cic_context, $self->{_cic_context} = $pvalue) |
409
|
|
|
|
|
|
|
} |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
sub __isub_encoding { |
412
|
1
|
|
|
1
|
|
3
|
my ($self, $isub_encoding, $pvalue) = @_; |
413
|
|
|
|
|
|
|
|
414
|
1
|
|
|
|
|
6
|
return $self->__add_parameter($isub_encoding, $self->{_isub_encoding} = $pvalue) |
415
|
|
|
|
|
|
|
} |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
sub __enumdi { |
418
|
1
|
|
|
1
|
|
4
|
my ($self, $enumdi) = @_; |
419
|
|
|
|
|
|
|
|
420
|
1
|
|
|
|
|
3
|
$self->{_has_enumdi} = 1; |
421
|
|
|
|
|
|
|
|
422
|
1
|
|
|
|
|
5
|
return $self->__add_parameter($enumdi) |
423
|
|
|
|
|
|
|
} |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
1; |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
=pod |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
=encoding UTF-8 |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
=head1 NAME |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
MarpaX::ESLIF::URI::tel - URI::tel syntax as per RFC3966, RFC4694, RFC4715, RFC4759, RFC4904 |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
=head1 VERSION |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
version 0.006 |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
=head1 SUBROUTINES/METHODS |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
MarpaX::ESLIF::URI::tel inherits, and eventually overwrites some, methods of MarpaX::ESLIF::URI::_generic. |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
=head2 $class->bnf |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
Overwrites parent's bnf implementation. Returns the BNF used to parse the input. |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
=head2 $class->grammar |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
Overwrite parent's grammar implementation. Returns the compiled BNF used to parse the input as MarpaX::ESLIF::Grammar singleton. |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
=head2 $self->number($type) |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
Returns the global or local number digits. C<$type> is either 'decoded' (default value), 'origin' or 'normalized'. |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
=head2 $self->is_global() |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
Returns a true value if number is global, else a false value. |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
=head2 $self->is_local() |
461
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
Returns a true value if number is local, else a false value. |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
=head2 $self->ext($type) |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
Returns the extension, if any. May be undef. C<$type> is either 'decoded' (default value), 'origin' or 'normalized'. |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
=head2 $self->isub($type) |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
Returns the isdn sub-address, if any. May be undef. C<$type> is either 'decoded' (default value), 'origin' or 'normalized'. |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
=head2 $self->isub_encoding($type) |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
Returns the isdn sub-address encoding for transmission, if any. May be undef. C<$type> is either 'decoded' (default value), 'origin' or 'normalized'. |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
=head2 $self->tgrp($type) |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
Returns the trunk group, if any. May be undef. C<$type> is either 'decoded' (default value), 'origin' or 'normalized'. |
479
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
=head2 $self->trunk_context($type) |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
Returns the trunk context, if any. May be undef. C<$type> is either 'decoded' (default value), 'origin' or 'normalized'. |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
=head2 $self->phone_context($type) |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
Returns the phone context, if any. May be undef. C<$type> is either 'decoded' (default value), 'origin' or 'normalized'. |
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
=head2 $self->rn($type) |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
Returns the rn, if any. May be undef. C<$type> is either 'decoded' (default value), 'origin' or 'normalized'. |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
=head2 $self->rn_context($type) |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
Returns the rn context, if any. May be undef. C<$type> is either 'decoded' (default value), 'origin' or 'normalized'. |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
=head2 $self->cic($type) |
497
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
Returns the cic, if any. May be undef. C<$type> is either 'decoded' (default value), 'origin' or 'normalized'. |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
=head2 $self->cic_context($type) |
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
Returns the cic context, if any. May be undef. C<$type> is either 'decoded' (default value), 'origin' or 'normalized'. |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
=head2 $self->has_npdi() |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
Returns a true value if the URI has the npdi parameter, else a false value. |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
=head2 $self->has_enumdi() |
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
Returns a true value if the URI has the enumdi parameter, else a false value. |
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
=head2 $self->parameters($type) |
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
Returns the parameters as an array of hashes that have the form { key => $key, value => $value }, where value may be undef, and with respect to the order of appearance in the URI. C<$type> is either 'decoded' (default value), 'origin' or 'normalized'. |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
=head1 NOTES |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
=over |
519
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
=item |
521
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
Errata L<203|https://www.rfc-editor.org/errata/eid203> has been applied. |
523
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
=item |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
Parameters are NOT reordered. So, since RFC3966 states that they B<MUST> appear in lexicographical order (except for C<ext>, C<isdn> and C<phone-context>), the parsing will fail in the input does not respect this sorting rule. |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
=item |
529
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
RFC4694 requires compliance with L<E.164|https://en.wikipedia.org/wiki/E.164> but this is not checked. |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
=item |
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
Any other extension, like premium rate category ("premrate" parameter), calling number verification ("verstat" parameter) etc... is not explicitly included unless an L<IETF|https://tools.ietf.org/> exists. Note that all known extensions are implicitly supported as long as their specification is just an extensions of the "parameter" or "par" rules. |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
=back |
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
=head1 SEE ALSO |
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
tel URI is totally case insensitive. |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
=head1 AUTHOR |
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
Jean-Damien Durand <jeandamiendurand@free.fr> |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
This software is copyright (c) 2017 by Jean-Damien Durand. |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
551
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
=cut |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
__DATA__ |
556
|
|
|
|
|
|
|
# |
557
|
|
|
|
|
|
|
# Reference: https://tools.ietf.org/html/rfc3966#section-3 |
558
|
|
|
|
|
|
|
# |
559
|
|
|
|
|
|
|
<telephone URI> ::= <telephone scheme> ":" <telephone subscriber> action => _action_string |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
<telephone scheme> ::= "tel":i action => _action_scheme |
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
<telephone subscriber> ::= <global number> |
564
|
|
|
|
|
|
|
| <local number> |
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
<global number> ::= <global number digits> pars action => __global |
567
|
|
|
|
|
|
|
<local number> ::= <local number digits> pars context pars action => __local |
568
|
|
|
|
|
|
|
pars ::= par* |
569
|
|
|
|
|
|
|
par ::= parameter |
570
|
|
|
|
|
|
|
| extension |
571
|
|
|
|
|
|
|
| <isdn subaddress> |
572
|
|
|
|
|
|
|
| <trunk group> |
573
|
|
|
|
|
|
|
| <trunk context> |
574
|
|
|
|
|
|
|
<isdn subaddress> ::= ";isub=":i <uric many> action => __isub |
575
|
|
|
|
|
|
|
<trunk group> ::= ";tgrp=":i <trunk group label> action => __tgrp |
576
|
|
|
|
|
|
|
<trunk context> ::= ";trunk-context=":i descriptor action => __trunk_context |
577
|
|
|
|
|
|
|
<trunk group label unit> ::= unreserved |
578
|
|
|
|
|
|
|
| <pct encoded> |
579
|
|
|
|
|
|
|
| <trunk group unreserved> |
580
|
|
|
|
|
|
|
<trunk group unreserved> ::= [/&+$] |
581
|
|
|
|
|
|
|
<trunk group label> ::= <trunk group label unit>+ |
582
|
|
|
|
|
|
|
extension ::= ";ext=":i <phonedigit many> action => __ext |
583
|
|
|
|
|
|
|
context ::= ";phone-context=":i descriptor action => __phone_context |
584
|
|
|
|
|
|
|
descriptor ::= domainname |
585
|
|
|
|
|
|
|
| <global number digits> |
586
|
|
|
|
|
|
|
# |
587
|
|
|
|
|
|
|
# The <global number digits> and <local number digits> are ambiguous because |
588
|
|
|
|
|
|
|
# <phonedigit> contains DIGIT, and <phonedigit hex> contains HEXDIG |
589
|
|
|
|
|
|
|
# |
590
|
|
|
|
|
|
|
# What W3C wanted to express with <global number digits> is that it must contains |
591
|
|
|
|
|
|
|
# at least one DIGIT everywhere |
592
|
|
|
|
|
|
|
# Original expression was: <global number digits> ::= "+" <phonedigit any> DIGIT <phonedigit any> |
593
|
|
|
|
|
|
|
# Fixed expression is taking advantage of the greedy nature of regexp: |
594
|
|
|
|
|
|
|
<global number digits> ::= /\+[0-9.()-]*[0-9][0-9.()-]*/ action => __number |
595
|
|
|
|
|
|
|
|
596
|
|
|
|
|
|
|
# |
597
|
|
|
|
|
|
|
# Same remark for <local number digits>: <phonedigit hex> |
598
|
|
|
|
|
|
|
# Original expression was: <local number digits> ::= <phonedigit hex any> <local number digits sep> <phonedigit hex any> |
599
|
|
|
|
|
|
|
# Fixed expression is: |
600
|
|
|
|
|
|
|
<local number digits> ::= /[0-9A-Fa-f*#.()-]*[0-9A-Fa-f*#][0-9A-Fa-f*#.()-]*/ action => __number |
601
|
|
|
|
|
|
|
# <local number digits sep> ::= HEXDIG |
602
|
|
|
|
|
|
|
# | "*" |
603
|
|
|
|
|
|
|
# | "#" |
604
|
|
|
|
|
|
|
<domainlabel and dot> ::= domainlabel "." |
605
|
|
|
|
|
|
|
<domainlabels> ::= <domainlabel and dot>* |
606
|
|
|
|
|
|
|
domainname ::= <domainlabels> toplabel "." |
607
|
|
|
|
|
|
|
| <domainlabels> toplabel |
608
|
|
|
|
|
|
|
domainlabel ::= /[A-Za-z0-9-](?:[A-Za-z0-9-]*[A-Za-z0-9])?/ |
609
|
|
|
|
|
|
|
toplabel ::= /[A-Za-z](?:[A-Za-z0-9-]*[A-Za-z0-9])?/ |
610
|
|
|
|
|
|
|
parameter ::= ";" pname action => __parameter |
611
|
|
|
|
|
|
|
| ";" pname "=" pvalue action => __parameter |
612
|
|
|
|
|
|
|
pname ::= /[A-Za-z0-9-]+/ action => __pname |
613
|
|
|
|
|
|
|
pvalue ::= <paramchar many> |
614
|
|
|
|
|
|
|
paramchar ::= <param unreserved> |
615
|
|
|
|
|
|
|
| <tel unreserved> |
616
|
|
|
|
|
|
|
| <pct encoded> |
617
|
|
|
|
|
|
|
<paramchar many> ::= paramchar+ |
618
|
|
|
|
|
|
|
<tel unreserved> ::= alphanum |
619
|
|
|
|
|
|
|
| mark |
620
|
|
|
|
|
|
|
mark ::= [-_.!~*'()] |
621
|
|
|
|
|
|
|
<param unreserved> ::= [\[\]/:&+$] |
622
|
|
|
|
|
|
|
phonedigit ::= DIGIT |
623
|
|
|
|
|
|
|
| <visual separator> |
624
|
|
|
|
|
|
|
<phonedigit many> ::= phonedigit+ action => __number |
625
|
|
|
|
|
|
|
<visual separator> ::= [-.()] |
626
|
|
|
|
|
|
|
alphanum ::= [A-Za-z0-9] |
627
|
|
|
|
|
|
|
<tel reserved> ::= [;/?:@&=+$,] |
628
|
|
|
|
|
|
|
uric ::= <unreserved> |
629
|
|
|
|
|
|
|
| <pct encoded> |
630
|
|
|
|
|
|
|
| <tel reserved> |
631
|
|
|
|
|
|
|
<uric many> ::= uric+ |
632
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
# |
634
|
|
|
|
|
|
|
## RFC 4694 |
635
|
|
|
|
|
|
|
# |
636
|
|
|
|
|
|
|
parameter ::= rn |
637
|
|
|
|
|
|
|
| cic |
638
|
|
|
|
|
|
|
| npdi |
639
|
|
|
|
|
|
|
rn ::= ";rn=":i <global rn> action => __rn |
640
|
|
|
|
|
|
|
| ";rn=":i <local rn> action => __rn |
641
|
|
|
|
|
|
|
npdi ::= ";npdi":i action => __npdi |
642
|
|
|
|
|
|
|
cic ::= ";cic=":i <global cic> action => __cic |
643
|
|
|
|
|
|
|
| ";cic=":i <local cic> action => __cic |
644
|
|
|
|
|
|
|
<global rn> ::= <global hex digits> |
645
|
|
|
|
|
|
|
# The first "hex-phonedigit" value in "local-rn" MUST be a hex-decimal digit. |
646
|
|
|
|
|
|
|
<local rn> ::= HEXDIG <hex phonedigit any> <rn context> |
647
|
|
|
|
|
|
|
<rn context> ::= ";rn-context=":i <rn descriptor> action => __rn_context |
648
|
|
|
|
|
|
|
<rn descriptor> ::= domainname |
649
|
|
|
|
|
|
|
| <global hex digits> |
650
|
|
|
|
|
|
|
<global hex digits> ::= "+" /[0-9]{1,3}/ <hex phonedigit any> |
651
|
|
|
|
|
|
|
<hex phonedigit> ::= HEXDIG |
652
|
|
|
|
|
|
|
| <visual separator> |
653
|
|
|
|
|
|
|
<global cic> ::= <global hex digits> |
654
|
|
|
|
|
|
|
# The first "hex-phonedigit" value in "local-rn" MUST be a hex-decimal digit. |
655
|
|
|
|
|
|
|
<local cic> ::= HEXDIG <hex phonedigit any> <cic context> |
656
|
|
|
|
|
|
|
<cic context> ::= ";cic-context=":i <rn descriptor> action => __cic_context |
657
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
<hex phonedigit any> ::= <hex phonedigit>* action => __number |
659
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
# |
661
|
|
|
|
|
|
|
# RFC4715 |
662
|
|
|
|
|
|
|
# |
663
|
|
|
|
|
|
|
parameter ::= ";isub-encoding=":i <isub encoding value> action => __isub_encoding |
664
|
|
|
|
|
|
|
# |
665
|
|
|
|
|
|
|
# No need to set "nsap-ia5", "nsap-bcd" or "nsap" explicitly: rfc4715token will catch them |
666
|
|
|
|
|
|
|
<isub encoding value> ::= rfc4715token |
667
|
|
|
|
|
|
|
rfc4715token ::= <uric many> |
668
|
|
|
|
|
|
|
|
669
|
|
|
|
|
|
|
# |
670
|
|
|
|
|
|
|
## RFC 4759 |
671
|
|
|
|
|
|
|
# |
672
|
|
|
|
|
|
|
parameter ::= enumdi |
673
|
|
|
|
|
|
|
enumdi ::= ";enumdi":i action => __enumdi |