/[suikacvs]/messaging/manakai/lib/Message/Field/Params.pm
Suika

Contents of /messaging/manakai/lib/Message/Field/Params.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.16 - (hide annotations) (download)
Sat Jul 6 10:30:43 2002 UTC (22 years, 4 months ago) by wakaba
Branch: MAIN
Changes since 1.15: +3 -2 lines
2002-06-29  Wakaba <w@suika.fam.cx>

	* ContentType.pm, Params.pm, ValueParams.pm,
	XMoe.pm: Rewritten.

1 wakaba 1.1
2     =head1 NAME
3    
4 wakaba 1.7 Message::Field::Params --- Perl module for Internet message
5     field body consist of parameters, such as C<Content-Type:> field
6 wakaba 1.1
7     =cut
8    
9     package Message::Field::Params;
10     use strict;
11     require 5.6.0;
12     use re 'eval';
13 wakaba 1.14 use vars qw(%DEFAULT @ISA %REG $VERSION);
14 wakaba 1.16 $VERSION=do{my @r=(q$Revision: 1.15 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r};
15 wakaba 1.3 require Message::Util;
16 wakaba 1.15 require Message::MIME::Charset;
17 wakaba 1.7 require Message::Field::Structured;
18     push @ISA, qw(Message::Field::Structured);
19    
20     use overload '""' => sub { $_[0]->stringify },
21     '0+' => sub { $_[0]->count },
22     '.=' => sub { $_[0]->add ($_[1], ['', value => 1]); $_[0] },
23     fallback => 1;
24    
25 wakaba 1.14 %REG = %Message::Util::REG;
26 wakaba 1.15
27     $REG{S_parameter} = qr/(?:[^\x22\x28\x3B\x3C]|$REG{comment}|$REG{quoted_string}|$REG{angle_quoted})+/;
28     $REG{S_parameter_separator} = qr/;/;
29     $REG{S_comma_parameter} = qr/(?:[^\x22\x28\x2C\x3C]|$REG{comment}|$REG{quoted_string}|$REG{angle_quoted})+/;
30     $REG{S_comma_parameter_separator} = qr/,/;
31     $REG{MS_parameter_avpair} = qr/([^\x22\x3C\x3D]+)=([\x00-\xFF]*)/;
32 wakaba 1.1
33 wakaba 1.14 %DEFAULT = (
34 wakaba 1.15 -_HASH_NAME => 'params',
35     -_MEMBERS => [qw/params/],
36     -_METHODS => [qw/add replace delete item parameter scan/],
37     ## count item_exist <- not implemented yet
38     -accept_coderange => '7bit',
39     -by => 'attribute',
40     #encoding_after_encode
41     #encoding_before_decode
42     #field_param_name
43     #field_name
44     #field_ns
45     #format
46     #header_default_charset
47     #header_default_charset_input
48     #hook_encode_string
49     #hook_decode_string
50     -output_comment => 1,
51     -output_parameter_extension => 0,
52     -parameter_rule => 'S_parameter', ## regex name of parameter
53     -parameter_attribute_case_sensible => 0,
54     -parameter_attribute_unsafe_rule => 'NON_http_attribute_char',
55     -parameter_av_Mrule => 'MS_parameter_avpair',
56     -parameter_no_value_attribute_unsafe_rule => 'NON_http_attribute_char',
57     -parameter_value_max_length => 60,
58     -parameter_value_split_length => 35,
59     -parameter_value_unsafe_rule => 'NON_http_attribute_char',
60     #parse_all
61     -separator => '; ',
62     -separator_rule => 'parameter_separator',
63     -use_comment => 1,
64     -use_parameter_extension => 1,
65     #value_type
66 wakaba 1.14 );
67    
68     =head1 CONSTRUCTORS
69    
70     The following methods construct new objects:
71    
72     =over 4
73    
74     =cut
75    
76     ## Initialize of this class -- called by constructors
77     sub _init ($;%) {
78     my $self = shift;
79     my %options = @_;
80 wakaba 1.7 $self->SUPER::_init (%DEFAULT, %options);
81     $self->{param} = [];
82 wakaba 1.15 my $field = $self->{option}->{field_name};
83     if ($field eq 'p3p') {
84     $self->{option}->{parameter_rule} = 'S_comma_parameter';
85     $self->{option}->{separator_rule} = 'S_comma_parameter_separator';
86 wakaba 1.8 $self->{option}->{separator} = ', ';
87     }
88 wakaba 1.15 if ($self->{option}->{format} =~ /news-usefor/) {
89     $self->{option}->{accept_coderange} = '8bit';
90     } elsif ($self->{option}->{format} =~ /http/) {
91     $self->{option}->{accept_coderange} = 'binary';
92     }
93 wakaba 1.7 }
94    
95     =item $p = Message::Field::Params->new ([%options])
96    
97     Constructs a new object. You might pass some options as parameters
98     to the constructor.
99    
100     =cut
101    
102 wakaba 1.14 ## Inherited
103 wakaba 1.1
104 wakaba 1.7 =item $p = Message::Field::Params->parse ($field-body, [%options])
105 wakaba 1.1
106 wakaba 1.7 Constructs a new object with given field body. You might pass
107     some options as parameters to the constructor.
108 wakaba 1.1
109     =cut
110    
111     sub parse ($$;%) {
112     my $class = shift;
113 wakaba 1.7 my $self = bless {}, $class;
114 wakaba 1.1 my $body = shift;
115 wakaba 1.7 $self->_init (@_);
116 wakaba 1.15 my @param;
117     $body =~ s{
118     ($REG{ $self->{option}->{parameter_rule} })
119     (?: $REG{ $self->{option}->{separator_rule} } | $ )
120     }{
121     push @param, $self->_parse_parameter_item ($1, $self->{option});
122     '';
123     }gesx;
124     $self->_decode_parameters (\@param, $self->{option});
125     $self->_save_parameters (\@param, $self->{option});
126 wakaba 1.1 $self;
127     }
128    
129 wakaba 1.15 ## $self->_parse_parameter_item ($item, \%option)
130     ## -- parses a parameter item (into attribute/value pair or no-value-attribute)
131     sub _parse_parameter_item ($$\%) {
132     my $self = shift;
133     my ($item, $option) = @_;
134     my @comment;
135     ($item, @comment) = $self->Message::Util::delete_comment_to_array
136     ($item, -use_angle_quoted);
137     $item =~ s/^$REG{WSP}+//g;
138     $item =~ s/$REG{WSP}+$//g;
139     my %item;
140     if ($item =~ /^$REG{ $option->{parameter_av_Mrule} }$/) {
141     my $encoded = 0;
142     ($item{attribute}, $item{value}) = ($1, $2);
143     $item{attribute} =~ tr/\x09\x0A\x0D\x20//d;
144     $item{value} =~ s/^$REG{WSP}+//g;
145     if ($option->{use_parameter_extension}
146     && $item{attribute} =~ /^([^*]+)(?:\*([0-9]+)(\*)?|(\*))\z/) {
147     $item{attribute} = $1;
148     $item{section_no} = $2;
149     $encoded = $3 || $4;
150     $item{section_no} = -1 if $4;
151     if ($item{section_no} <= 0 && $encoded
152     && $item{value} =~ /^([^']*)'([^']*)'([\x00-\xFF]*)$/) {
153     $item{charset} = $1; $item{charset} =~ tr/\x09\x0A\x0D\x20//d;
154     $item{language} = $2; $item{language} =~ tr/\x09\x0A\x0D\x20//d;
155     $item{value} = $3; $item{value} =~ s/^$REG{WSP}+//g;
156     }
157     if ($encoded) {
158     $item{value} =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/chr(hex($1))/ge;
159     }
160     } else {
161     $item{section_no} = -1;
162 wakaba 1.1 }
163 wakaba 1.15 ($item{value}, $encoded) = Message::Util::unquote_if_quoted_string ($item{value}) unless $encoded;
164     ($item{value}, $encoded) = Message::Util::unquote_if_angle_quoted ($item{value}) unless $encoded;
165     $item{charset} = '*bare' if !$encoded && !$item{charset};
166     $item{attribute} = lc $item{attribute}
167     unless $option->{parameter_attribute_case_sensible};
168 wakaba 1.1 } else {
169 wakaba 1.15 my $encoded = 0;
170     ($item, $encoded) = Message::Util::unquote_if_quoted_string ($item) unless $encoded;
171     ($item, $encoded) = Message::Util::unquote_if_angle_quoted ($item) unless $encoded;
172     $item{attribute} = $item;
173     $item{charset} = '*bare' if !$encoded;
174     $item{no_value} = 1;
175     }
176     $item{comment} = \@comment;
177     \%item;
178     }
179    
180     ## $self->_decode_parameters (\@parameter, \%option)
181     ## -- join RFC 2231 splited fragments and decode each parameter
182     sub _decode_parameters ($\@\%) {
183     my $self = shift;
184     my ($param, $option) = @_;
185     my %fragment;
186     my @fparameter;
187     for my $parameter (@$param) {
188     if ($parameter->{no_value}) {
189     my %item;
190     $item{no_value} = 1;
191     $item{comment} = $parameter->{comment};
192     if ($parameter->{charset} ne '*bare') {
193     my %s = &{$self->{option}->{hook_decode_string}}
194     ($self, $parameter->{attribute},
195     charset => $option->{encoding_before_decode},
196     type => 'parameter/no-value-attribute');
197     if ($s{charset}) { ## Convertion failed
198     $item{charset} = $s{charset};
199     }
200     $item{attribute} = $s{value};
201     } else {
202     $item{attribute} = $parameter->{attribute};
203     }
204     $parameter = \%item;
205     } elsif ($parameter->{section_no} < 0) {
206     my %item;
207     $item{attribute} = $parameter->{attribute};
208     $item{language} = $parameter->{language} if $parameter->{language};
209     $item{comment} = $parameter->{comment};
210     if ($parameter->{charset} ne '*bare') {
211     my %s = &{$self->{option}->{hook_decode_string}}
212     ($self, $parameter->{value},
213     charset => $parameter->{charset} || $option->{encoding_before_decode},
214     type => 'parameter/value/quoted-string');
215     if ($s{charset}) { ## Convertion failed
216     $item{charset} = $s{charset};
217     } elsif ($parameter->{charset}) {
218     $item{output_charset} = $parameter->{charset};
219 wakaba 1.1 }
220 wakaba 1.15 $item{value} = $s{value};
221 wakaba 1.1 } else {
222 wakaba 1.15 $item{value} = $parameter->{value};
223     }
224     $parameter = \%item;
225     } else { ## fragment
226     $fragment{ $parameter->{attribute} }->[ $parameter->{section_no} ]
227     = $parameter->{value};
228     if ($parameter->{section_no} == 0) {
229     $fragment{'*property'}->{ $parameter->{attribute} }
230     ->{language} = $parameter->{language};
231     $fragment{'*property'}->{ $parameter->{attribute} }
232     ->{charset} = $parameter->{charset};
233     }
234     if (ref $parameter->{comment} && @{$parameter->{comment}} > 0) {
235     push @{ $fragment{'*property'}->{ $parameter->{attribute} }
236     ->{comment} }, @{$parameter->{comment}};
237 wakaba 1.1 }
238 wakaba 1.15 $parameter = undef;
239     }
240     }
241     for (keys %fragment) {
242     next if $_ eq '*property';
243     my %item;
244     $item{attribute} = $_;
245     $item{comment} = $fragment{'*property'}->{ $item{attribute} }->{comment};
246     $item{language} = $fragment{'*property'}->{ $item{attribute} }->{language};
247     delete $item{language} unless $item{language};
248     my $charset = $fragment{'*property'}->{ $item{attribute} }->{charset};
249     my %s = &{$self->{option}->{hook_decode_string}}
250     ($self, join ('', @{ $fragment{ $item{attribute} } }),
251     charset => $charset || $option->{encoding_before_decode},
252     type => 'parameter/extended-value/encoded');
253     if ($s{charset}) { ## Convertion failed
254     $item{charset} = $s{charset};
255     } elsif ($charset) {
256     $item{output_charset} = $charset;
257 wakaba 1.3 }
258 wakaba 1.15 $item{value} = $s{value};
259     push @fparameter, \%item;
260 wakaba 1.1 }
261 wakaba 1.15 @$param = (grep { ref $_ eq 'HASH' } @$param, @fparameter);
262 wakaba 1.11 }
263    
264 wakaba 1.15 ## $self->_parse_values_of_paramters (\@parameter, \%option)
265 wakaba 1.11 ## --- Parse each values of parameters
266 wakaba 1.15 sub _parse_values_of_parameters ($\@\%) {
267 wakaba 1.11 my $self = shift;
268 wakaba 1.15 my ($param, $option) = @_;
269     @$param = map {
270     if (!$_->{no_value}) {
271     $_->{value} = $self->_parse_value ($_->{attribute} => $_->{value});
272     } else {
273     $_->{value} = $self->_parse_value ('*no_value_attribute' => $_->{value});
274 wakaba 1.9 }
275     $_;
276 wakaba 1.15 } @$param;
277     }
278    
279     ## $self->_save_parameters (\@parameter, \%option)
280     ## -- Save parameters in $self
281     sub _save_parameters ($\@\%) {
282     my $self = shift;
283     my ($param, $option) = @_;
284     $self->_parse_values_of_parameters ($param, $option) if $option->{parse_all};
285     $self->{ $option->{_HASH_NAME} } = $param;
286 wakaba 1.1 }
287 wakaba 1.15 *__save_parameters = \&_save_parameters;
288    
289 wakaba 1.1
290 wakaba 1.7 =back
291    
292     =head1 METHODS
293    
294     =over 4
295    
296     =item $p->add ($name => [$value], [$name => $value,...])
297 wakaba 1.1
298     Adds parameter name=value pair.
299    
300     Example:
301 wakaba 1.7 $p->add (title => 'foo of bar'); ## title="foo of bar"
302     $p->add (subject => 'hogehoge, foo'); ## subject*=''hogehoge%2C%20foo
303     $p->add (foo => ['bar', language => 'en']) ## foo*='en'bar
304     $p->add ('text/plain', ['', value => 1]) ## text/plain
305 wakaba 1.1
306     This method returns array reference of (name, {value => value, attribute...}).
307    
308     Available options: charset (charset name), language (language tag),
309     value (1/0, see example above).
310    
311     =cut
312    
313 wakaba 1.14 sub _add_hash_check ($$$\%) {
314     my $self = shift;
315     my ($name, $value, $option) = @_;
316     my $value_option = {};
317     if (ref $value eq 'ARRAY') {
318     ($value, %$value_option) = @$value;
319     }
320 wakaba 1.15 ## -- attribute only (no value) parameter
321     if ($value_option->{no_value}) {
322     $name = $self->_parse_value ('*no_value_attribute' => $name) if $$option{parse};
323     return (1, $name => {
324     attribute => $name, no_value => 1,
325     language => $value_option->{language},
326     comment => $value_option->{comment},
327     });
328 wakaba 1.14 }
329 wakaba 1.15 ## -- attribute=value pair
330     if ($$option{validate} && $name =~ /^$REG{NON_http_attribute_char}$/) {
331     if ($$option{dont_croak}) {
332     return (0);
333 wakaba 1.7 } else {
334 wakaba 1.15 Carp::croak qq{add: $name: Invalid parameter name};
335 wakaba 1.7 }
336 wakaba 1.1 }
337 wakaba 1.15 $value = $self->_parse_value ($name => $value) if $$option{parse};
338     (1, $name => {
339     attribute => $name, value => $value,
340     output_charset => $value_option->{charset},
341     charset => $value_option->{current_charset},
342     language => $value_option->{language},
343     comment => $value_option->{comment},
344     });
345 wakaba 1.1 }
346 wakaba 1.7
347 wakaba 1.15 *_add_return_value = \&_replace_return_value;
348    
349     ## (1/0, $name => $value) = $self->_replace_hash_check ($name => $value, \%option)
350     ## -- Checks given value and prepares saving value (hash version)
351     *_replace_hash_check = \&_add_hash_check;
352    
353     ## $value = $self->_replace_hash_shift (\%values, $name, $option)
354     ## -- Returns a value (from %values) and deletes it from %values
355     ## (like CORE::shift for array).
356     sub _replace_hash_shift ($\%$\%) {
357     shift; my $r = shift; my $n = $_[0]->{attribute};
358     if ($$r{$n}) {
359     my $d = $$r{$n};
360     $$r{$n} = undef;
361     return $d;
362     }
363     undef;
364     }
365    
366     ## $value = $self->_replace_return_value (\$item, \%option)
367     ## -- Returns returning value of replace method
368     sub _replace_return_value ($\$\%) {
369     my $self = shift;
370     my ($item, $value) = @_;
371     if ($$item->{no_value}) {
372     $$item->{attribute};
373     } else {
374     $$item->{value};
375 wakaba 1.1 }
376     }
377    
378 wakaba 1.15 ## 1/0 = $self->_delete_match ($by, \$item, \%delete_list, \%option)
379     ## -- Checks and returns whether given item is matched with
380     ## deleting item list
381     sub _delete_match ($$\$\%\%) {
382     my $self = shift;
383     my ($by, $item, $list, $option) = @_;
384     return 0 unless ref $$item; ## Already removed
385     if ($by eq 'attribute' || $by eq 'name') {
386     return 1 if $$list{ $$item->{attribute} };
387     } elsif ($by eq 'value') {
388     return 1 if $$list{ $$item->{value} };
389     } elsif ($by eq 'charset') {
390     return 1 if $$list{ $$item->{output_charset} } || $$list{ $$item->{charset} };
391     } elsif ($by eq 'language') {
392     return 1 if $$list{ $$item->{language} };
393     } elsif ($by eq 'type') {
394     if ($$item->{no_value}) {
395     return 1 if $$list{no_value_attribute};
396     } else {
397     return 1 if $$list{attribute_value_pair};
398 wakaba 1.1 }
399     }
400 wakaba 1.15 0;
401 wakaba 1.1 }
402    
403 wakaba 1.15 ## Delete empty items
404     sub _delete_empty ($) {
405 wakaba 1.1 my $self = shift;
406 wakaba 1.15 my $array = $self->{option}->{_HASH_NAME};
407     $self->{ $array } = [grep { ref $_ } @{$self->{ $array }}] if $array;
408 wakaba 1.1 }
409    
410 wakaba 1.15 =item @param = $p->parameter ($name => ($new_value), (%option))
411 wakaba 1.1
412    
413 wakaba 1.15 =cut
414    
415     sub parameter ($;@) {
416 wakaba 1.1 my $self = shift;
417 wakaba 1.15 if (@_ == 2) { ## $p->parameter (hoge => 'foo')
418     $self->replace (@_);
419     } else { ## $p->parameter ('foo')
420     $self->item (@_);
421 wakaba 1.1 }
422     }
423    
424 wakaba 1.15 *_item_match = \&_delete_match;
425     *_item_return_value = \&_replace_return_value;
426 wakaba 1.1
427 wakaba 1.15 ## $item = $self->_item_new_value ($name, \%option)
428     ## -- Returns new item with key of $name (called when
429     ## no returned value is found and -new_value_unless_exist
430     ## option is true)
431     sub _item_new_value ($$\%) {
432 wakaba 1.1 my $self = shift;
433 wakaba 1.15 my ($key, $option) = @_;
434     if ($option->{by} eq 'attribute' || $option->{by} eq 'name') {
435     return {attribute => $key};
436     }
437     undef;
438 wakaba 1.1 }
439    
440 wakaba 1.15 ## TODO: Implement count,item_exist method
441 wakaba 1.1
442 wakaba 1.7 =item $field-body = $p->stringify ()
443 wakaba 1.1
444 wakaba 1.7 Returns C<field-body> as a string.
445 wakaba 1.1
446     =cut
447    
448     sub stringify ($;%) {
449     my $self = shift;
450 wakaba 1.15 my %o = @_; my %option = %{$self->{option}};
451 wakaba 1.7 for (grep {/^-/} keys %o) {$option{substr ($_, 1)} = $o{$_}}
452 wakaba 1.15 $option{output_parameter_extension} = 0
453     unless $option{use_parameter_extension};
454     $option{output_comment} = 0 unless $option{use_comment};
455 wakaba 1.7 $self->_delete_empty;
456 wakaba 1.15 my @param;
457     $self->scan( sub {shift;
458     my ($item, $option) = @_;
459     my $r = 1;
460     ($r, $item) = $self->_stringify_param_check ($item, $option);
461     return unless $r;
462     my $comment = '';
463     if ($option->{output_comment} && ref $item->{comment}
464     && @{$item->{comment}} > 0) {
465     my @c;
466     for (@{$item->{comment}}) {
467     push @c, '('. $self->Message::Util::encode_ccontent ($_) .')';
468     }
469     $comment = ' '. join ' ', @c;
470     }
471     if ($item->{no_value}) {
472     push @param, Message::Util::quote_unsafe_string ($item->{attribute},
473     unsafe => $option->{parameter_no_value_attribute_unsafe_rule}).$comment;
474     } else {
475     my $xparam = 0;
476     my $attribute = $item->{attribute};
477     return unless length $attribute;
478     my $value = ''.$item->{value};
479     if ($attribute =~ /$REG{ $option->{parameter_attribute_unsafe_rule} }/) {
480     #return 0;
481     $attribute =~ s/($REG{NON_http_attribute_char})/sprintf('%%%02X', ord $1)/ge;
482     }
483     my %e;
484     if ($option->{output_parameter_extension}) {
485     if ($item->{charset}) {
486     %e = %$item;
487     } else {
488     %e = &{$self->{option}->{hook_encode_string}}
489     ($self, $value,
490     charset => $item->{output_charset} || $option->{encoding_after_encode},
491     current_charset => $option->{header_default_charset},
492     language => $item->{language},
493     type => 'parameter/value');
494     }
495     $xparam = 1 if (length $e{value} > $option->{parameter_value_max_length})
496     || $e{charset}
497     || $e{language}
498     || $e{value} =~ /\x0D|\x0A/s
499 wakaba 1.16 || $e{value} =~ /$REG{WSP}$REG{WSP}+/s
500 wakaba 1.15 || ($option->{accept_coderange} eq '7bit'
501     && $e{value} =~ /[\x80-\xFF]/)
502     || ($option->{accept_coderange} ne 'binary'
503     && $e{value} =~ /\x00/)
504     ;
505     } else { ## Don't use paramext
506     if ($item->{charset}) { ## But parameter value is undecodable charset value
507     %e = %$item;
508     $xparam = 1;
509 wakaba 1.1 } else {
510 wakaba 1.15 %e = &{$self->{option}->{hook_encode_string}}
511     ($self, $value,
512     charset => $option->{encoding_after_encode},
513     current_charset => $option->{header_default_charset},
514     language => $item->{language},
515     type => 'parameter/value');
516     }
517     }
518     if ($xparam) {
519     if (length $e{value} > $option->{parameter_value_max_length}) {
520     for my $i (0..(length ($e{value})
521     /$option->{parameter_value_split_length})) {
522     my $v = substr ($e{value},
523     $i * $option->{parameter_value_split_length},
524     $option->{parameter_value_split_length});
525     if ($i == 0) {
526     $v
527     =~ s/($REG{NON_http_attribute_char})/sprintf('%%%02X', ord $1)/ge;
528     my $charset = Message::MIME::Charset::name_minimumize
529     ($e{charset} || $option->{header_default_charset}, $value);
530     push @param, sprintf q{%s*0*=%s'%s'%s%s}, $attribute,
531     $charset, $e{language}, $v, $comment;
532     } else { # $i > 0
533     if ($e{charset} || $v =~ /\x0A|\x0D/s
534     || ($option->{accept_coderange} ne 'binary' && $v =~ /\x00/)
535     || ($option->{accept_coderange} eq '7bit' && $v =~ /[\x80-\xFF]/)) {
536     $v =~ s/($REG{NON_http_attribute_char})/sprintf('%%%02X', ord $1)/ge;
537     push @param, sprintf q{%s*%d*=%s}, $attribute, $i, $v;
538     } else {
539     $v = Message::Util::quote_unsafe_string ($v,
540     unsafe => $option->{parameter_value_unsafe_rule});
541     $v = q{""} if length $v == 0;
542     push @param, sprintf q{%s*%d=%s}, $attribute, $i, $v;
543     }
544 wakaba 1.1 }
545     }
546     } else {
547 wakaba 1.15 $e{value}
548     =~ s/($REG{NON_http_attribute_char})/sprintf('%%%02X', ord $1)/ge;
549     unless ($e{charset}) {
550     $e{charset} = Message::MIME::Charset::name_minimumize
551     ($option->{header_default_charset}, $e{value});
552 wakaba 1.1 }
553 wakaba 1.15 push @param, sprintf q{%s*=%s'%s'%s%s}, $attribute,
554     $e{charset}, $e{language}, $e{value}, $comment;
555 wakaba 1.1 }
556     } else {
557 wakaba 1.15 $e{value} = Message::Util::quote_unsafe_string ($e{value},
558     unsafe => $option->{parameter_value_unsafe_rule});
559     $e{value} = q{""} if length $e{value} == 0;
560     push @param, sprintf '%s=%s%s', $attribute, $e{value}, $comment;
561 wakaba 1.1 }
562 wakaba 1.15 }
563     }, options => \%option );
564     join $option{separator}, @param;
565 wakaba 1.1 }
566 wakaba 1.7 *as_string = \&stringify;
567 wakaba 1.1
568 wakaba 1.15 ## $self->_stringify_param_check (\%item, \%option)
569     ## -- Checks parameter (and modify if necessary).
570     ## Returns either 1 (ok) or 0 (don't output)
571     sub _stringify_param_check ($\%\%) {
572 wakaba 1.9 my $self = shift;
573 wakaba 1.15 my ($item, $option) = @_;
574     (1, $item);
575 wakaba 1.9 }
576    
577 wakaba 1.15 ## scan: Inherited
578    
579     ## TODO: ...
580     sub _scan_sort ($\@) {
581     #my $self = shift;
582     @{$_[1]};
583 wakaba 1.7 }
584    
585 wakaba 1.8 =item $option-value = $p->option ($option-name)
586 wakaba 1.1
587 wakaba 1.7 Gets option value.
588    
589 wakaba 1.8 =item $p->option ($option-name, $option-value, ...)
590 wakaba 1.7
591     Set option value(s). You can pass multiple option name-value pair
592     as parameter when setting.
593 wakaba 1.1
594     =cut
595    
596 wakaba 1.15 ## $self->_option_recursive (\%argv)
597     sub _option_recursive ($\%) {
598 wakaba 1.1 my $self = shift;
599 wakaba 1.15 my $o = shift;
600     for (@{$self->{ $self->{option}->{_HASH_NAME} }}) {
601     $_->{value}->option (%$o) if ref $_ && ref $_->{value};
602 wakaba 1.1 }
603     }
604    
605 wakaba 1.9 ## value_type: Inherited
606 wakaba 1.1
607 wakaba 1.8 =item $clone = $p->clone ()
608 wakaba 1.1
609 wakaba 1.7 Returns a copy of the object.
610 wakaba 1.1
611     =cut
612    
613 wakaba 1.15 ## Inherited
614 wakaba 1.7
615 wakaba 1.1 =head1 LICENSE
616    
617     Copyright 2002 wakaba E<lt>w@suika.fam.cxE<gt>.
618    
619     This program is free software; you can redistribute it and/or modify
620     it under the terms of the GNU General Public License as published by
621     the Free Software Foundation; either version 2 of the License, or
622     (at your option) any later version.
623    
624     This program is distributed in the hope that it will be useful,
625     but WITHOUT ANY WARRANTY; without even the implied warranty of
626     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
627     GNU General Public License for more details.
628    
629     You should have received a copy of the GNU General Public License
630     along with this program; see the file COPYING. If not, write to
631     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
632     Boston, MA 02111-1307, USA.
633    
634     =head1 CHANGE
635    
636     See F<ChangeLog>.
637 wakaba 1.16 $Date: 2002/06/29 09:31:45 $
638 wakaba 1.1
639     =cut
640    
641     1;

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24