10 |
use strict; |
use strict; |
11 |
require 5.6.0; |
require 5.6.0; |
12 |
use re 'eval'; |
use re 'eval'; |
13 |
use vars qw(@ISA %REG $VERSION); |
use vars qw(%DEFAULT @ISA %REG $VERSION); |
14 |
$VERSION=do{my @r=(q$Revision$=~/\d+/g);sprintf "%d."."%02d" x $#r,@r}; |
$VERSION=do{my @r=(q$Revision$=~/\d+/g);sprintf "%d."."%02d" x $#r,@r}; |
15 |
require Message::Util; |
require Message::Util; |
16 |
require Message::Field::Structured; |
require Message::Field::Structured; |
21 |
'.=' => sub { $_[0]->add ($_[1], ['', value => 1]); $_[0] }, |
'.=' => sub { $_[0]->add ($_[1], ['', value => 1]); $_[0] }, |
22 |
fallback => 1; |
fallback => 1; |
23 |
|
|
24 |
*REG = \%Message::Util::REG; |
%REG = %Message::Util::REG; |
25 |
## Inherited: comment, quoted_string, domain_literal, angle_quoted |
## Inherited: comment, quoted_string, domain_literal, angle_quoted |
26 |
## WSP, FWS, atext, atext_dot, token, attribute_char |
## WSP, FWS, atext, atext_dot, token, attribute_char |
27 |
## S_encoded_word |
## S_encoded_word |
42 |
$REG{M_parameter_extended_value} = qr/([^']*)'([^']*)'($REG{token}*)/; |
$REG{M_parameter_extended_value} = qr/([^']*)'([^']*)'($REG{token}*)/; |
43 |
## as defined by RFC 2231, but more naive. |
## as defined by RFC 2231, but more naive. |
44 |
|
|
45 |
|
%DEFAULT = ( |
46 |
=head1 CONSTRUCTORS |
-_HASH_NAME => 'param', |
|
|
|
|
The following methods construct new objects: |
|
|
|
|
|
=over 4 |
|
|
|
|
|
=cut |
|
|
|
|
|
## Initialize of this class -- called by constructors |
|
|
sub _init ($;%) { |
|
|
my $self = shift; |
|
|
my %options = @_; |
|
|
my %DEFAULT = ( |
|
47 |
-delete_fws => 1,## BUG: this option MUST be '1'. |
-delete_fws => 1,## BUG: this option MUST be '1'. |
48 |
## parameter parser cannot procede CFWS. |
## parameter parser cannot procede CFWS. |
49 |
#encoding_after_encode |
#encoding_after_encode |
61 |
-parse_all => 0, |
-parse_all => 0, |
62 |
-separator => '; ', |
-separator => '; ', |
63 |
-separator_regex => qr/$REG{FWS};$REG{FWS}/, |
-separator_regex => qr/$REG{FWS};$REG{FWS}/, |
64 |
|
-use_comment => 1, |
65 |
-use_parameter_extension => 0, |
-use_parameter_extension => 0, |
66 |
#value_type |
#value_type |
67 |
); |
); |
68 |
|
|
69 |
|
=head1 CONSTRUCTORS |
70 |
|
|
71 |
|
The following methods construct new objects: |
72 |
|
|
73 |
|
=over 4 |
74 |
|
|
75 |
|
=cut |
76 |
|
|
77 |
|
## Initialize of this class -- called by constructors |
78 |
|
sub _init ($;%) { |
79 |
|
my $self = shift; |
80 |
|
my %options = @_; |
81 |
$self->SUPER::_init (%DEFAULT, %options); |
$self->SUPER::_init (%DEFAULT, %options); |
82 |
$self->{param} = []; |
$self->{param} = []; |
83 |
my $fname = $self->{option}->{field_name}; |
my $fname = $self->{option}->{field_name}; |
92 |
} elsif ($self->{option}->{format} =~ /^http/) { |
} elsif ($self->{option}->{format} =~ /^http/) { |
93 |
$self->{option}->{encoding_before_decode} = 'iso-8859-1'; |
$self->{option}->{encoding_before_decode} = 'iso-8859-1'; |
94 |
$self->{option}->{encoding_after_decode} = 'iso-8859-1'; |
$self->{option}->{encoding_after_decode} = 'iso-8859-1'; |
95 |
} |
} ## TODO: news-usefor -> x-junet8 |
|
} |
|
|
|
|
|
## Initialization for new () method. |
|
|
sub _initialize_new ($;%) { |
|
|
## Nothing to do |
|
|
} |
|
|
|
|
|
## Initialization for parse () method. |
|
|
sub _initialize_parse ($;%) { |
|
|
## Nothing to do |
|
96 |
} |
} |
97 |
|
|
98 |
=item $p = Message::Field::Params->new ([%options]) |
=item $p = Message::Field::Params->new ([%options]) |
102 |
|
|
103 |
=cut |
=cut |
104 |
|
|
105 |
sub new ($;%) { |
## Inherited |
|
my $self = shift->SUPER::new (@_); |
|
|
$self->_initialize_new (@_); |
|
|
$self; |
|
|
} |
|
106 |
|
|
107 |
=item $p = Message::Field::Params->parse ($field-body, [%options]) |
=item $p = Message::Field::Params->parse ($field-body, [%options]) |
108 |
|
|
116 |
my $self = bless {}, $class; |
my $self = bless {}, $class; |
117 |
my $body = shift; |
my $body = shift; |
118 |
$self->_init (@_); |
$self->_init (@_); |
119 |
$self->_initialize_parse (@_); |
$body = Message::Util::delete_comment ($body) |
120 |
$body = Message::Util::delete_comment ($body); |
if $self->{option}->{use_comment}; |
121 |
$body = $self->_delete_fws ($body) if $self->{option}->{delete_fws}; |
$body = $self->_delete_fws ($body) if $self->{option}->{delete_fws}; |
122 |
my @b = (); |
my @b = (); |
123 |
$body =~ s{$REG{FWS}($REG{$self->{option}->{parameter_rule}}) |
$body =~ s{$REG{FWS}($REG{$self->{option}->{parameter_rule}}) |
164 |
my %s = &{$self->{option}->{hook_decode_string}} ($self, $s, |
my %s = &{$self->{option}->{hook_decode_string}} ($self, $s, |
165 |
language => $p->{language}, charset => $p->{charset}, |
language => $p->{language}, charset => $p->{charset}, |
166 |
type => 'parameter/encoded'); |
type => 'parameter/encoded'); |
167 |
|
if ($p->{charset} && !$s{charset}) { |
168 |
|
$p->{charset_to_be} = $p->{charset}; ## Original charset |
169 |
|
} |
170 |
($s, $p->{charset}, $p->{language}) = (@s{qw(value charset language)}); |
($s, $p->{charset}, $p->{language}) = (@s{qw(value charset language)}); |
171 |
} elsif ($p->{is_internal}) { |
} elsif ($p->{is_internal}) { |
172 |
$s = $p->{value}; |
$s = $p->{value}; |
178 |
($s, $p->{charset}, $p->{language}) = (@s{qw(value charset language)}); |
($s, $p->{charset}, $p->{language}) = (@s{qw(value charset language)}); |
179 |
} |
} |
180 |
push @ret, [$i->[0], {value => $s, language => $p->{language}, |
push @ret, [$i->[0], {value => $s, language => $p->{language}, |
181 |
charset => $p->{charset}, is_parameter => 1}]; |
charset => $p->{charset}, |
182 |
|
charset_to_be => $p->{charset_to_be}, |
183 |
|
is_parameter => 1}]; |
184 |
} else { |
} else { |
185 |
$part{$i->[0]}->[$p->{seq}] = { |
$part{$i->[0]}->[$p->{seq}] = { |
186 |
value => scalar Message::Util::unquote_if_quoted_string ($p->{value}), |
value => scalar Message::Util::unquote_if_quoted_string ($p->{value}), |
205 |
} @{$part{$name}}; |
} @{$part{$name}}; |
206 |
my %s = &{$self->{option}->{hook_decode_string}} ($self, $t, |
my %s = &{$self->{option}->{hook_decode_string}} ($self, $t, |
207 |
type => 'parameter/encoded'); |
type => 'parameter/encoded'); |
208 |
($t,@part{$name}->[0]->{qw(charset language)})=(@s{qw(value charset language)}); |
if ($part{$name}->[0]->{charset} && !$s{charset}) { ## Original charset |
209 |
|
$part{$name}->[0]->{charset_to_be} = $part{$name}->[0]->{charset}; |
210 |
|
} |
211 |
|
($t,@{$part{$name}->[0]}{qw(charset language)})=(@s{qw(value charset language)}); |
212 |
push @ret, [$name, {value => $t, charset => $part{$name}->[0]->{charset}, |
push @ret, [$name, {value => $t, charset => $part{$name}->[0]->{charset}, |
213 |
|
charset_to_be => $part{$name}->[0]->{charset_to_be}, |
214 |
language => $part{$name}->[0]->{language}, |
language => $part{$name}->[0]->{language}, |
215 |
is_parameter => 1}]; |
is_parameter => 1}]; |
216 |
} |
} |
265 |
|
|
266 |
=cut |
=cut |
267 |
|
|
268 |
sub add ($$;$%) { |
sub _add_hash_check ($$$\%) { |
269 |
|
my $self = shift; |
270 |
|
my ($name, $value, $option) = @_; |
271 |
|
my $value_option = {}; |
272 |
|
if (ref $value eq 'ARRAY') { |
273 |
|
($value, %$value_option) = @$value; |
274 |
|
} |
275 |
|
if ($value_option->{value}) { ## Non-value parameter |
276 |
|
$name = $self->_parse_value ('*novalue' => $name) if $$option{parse}; |
277 |
|
return (1, $name => [$name, {is_parameter => 0}]); |
278 |
|
} |
279 |
|
if ($$option{validate} && !$value_option->{value} |
280 |
|
&& $name =~ /^$REG{NON_http_attribute_char}$/) { |
281 |
|
if ($$option{dont_croak}) { |
282 |
|
return (0); |
283 |
|
} else { |
284 |
|
Carp::croak qq{add: $name: Invalid parameter name}; |
285 |
|
} |
286 |
|
$value = $self->_parse_value ($name => $value) if $$option{parse}; |
287 |
|
} |
288 |
|
(1, $name => [$name => {value => $value, is_parameter => 1, |
289 |
|
charset_to_be => $value_option->{charset}, |
290 |
|
language => $value_option->{language}, |
291 |
|
}]); |
292 |
|
} |
293 |
|
|
294 |
|
|
295 |
|
sub Xadd ($$;$%) { |
296 |
my $self = shift; |
my $self = shift; |
297 |
my %gp = @_; |
my %gp = @_; |
298 |
my %option = %{$self->{option}}; |
my %option = %{$self->{option}}; |
397 |
} |
} |
398 |
} |
} |
399 |
} |
} |
400 |
@ret; |
wantarray? @ret: undef; |
401 |
} |
} |
402 |
|
|
403 |
sub parameter_name ($$;$) { |
sub parameter_name ($$;$) { |
452 |
if ($v->{is_parameter}) { |
if ($v->{is_parameter}) { |
453 |
my ($encoded, @value) = (0, ''); |
my ($encoded, @value) = (0, ''); |
454 |
my (%e) = &{$self->{option}->{hook_encode_string}} ($self, |
my (%e) = &{$self->{option}->{hook_encode_string}} ($self, |
455 |
$v->{value}, current_charset => $v->{charset}, language => $v->{language}, |
$v->{value}, charset => $v->{charset_to_be}, |
456 |
|
current_charset => $v->{charset}, language => $v->{language}, |
457 |
type => 'parameter'); |
type => 'parameter'); |
458 |
if (!defined $e{value}) { |
if (!defined $e{value}) { |
459 |
$value[0] = undef; |
$value[0] = undef; |