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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.15 - (hide annotations) (download)
Sat Jun 15 07:15:59 2002 UTC (22 years, 5 months ago) by wakaba
Branch: MAIN
Changes since 1.14: +6 -4 lines
2002-06-15  wakaba <w@suika.fam.cx>

	* AngleQuoted.pm: New module.
	* Mailbox.pm, URI.pm: Use AngleQuoted.pm

1 wakaba 1.1
2     =head1 NAME
3    
4 wakaba 1.14 Message::Field::Structured --- A Perl Module for Internet
5     Message Structured Header Field Bodies
6 wakaba 1.1
7     =cut
8    
9     package Message::Field::Structured;
10     use strict;
11 wakaba 1.11 use vars qw(%DEFAULT $VERSION);
12 wakaba 1.15 $VERSION=do{my @r=(q$Revision: 1.14 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r};
13 wakaba 1.3 require Message::Util;
14 wakaba 1.5 use overload '""' => sub { $_[0]->stringify },
15     '.=' => sub { $_[0]->value_append ($_[1]) },
16 wakaba 1.14 #'eq' => sub { $_[0]->{field_body} eq $_[1] },
17     #'ne' => sub { $_[0]->{field_body} ne $_[1] },
18 wakaba 1.5 fallback => 1;
19 wakaba 1.1
20 wakaba 1.5 =head1 CONSTRUCTORS
21 wakaba 1.1
22 wakaba 1.5 The following methods construct new C<Message::Field::Structured> objects:
23 wakaba 1.1
24 wakaba 1.5 =over 4
25 wakaba 1.1
26 wakaba 1.5 =cut
27 wakaba 1.1
28 wakaba 1.5 ## Initialize of this class -- called by constructors
29 wakaba 1.11 %DEFAULT = (
30 wakaba 1.9 _ARRAY_NAME => '',
31 wakaba 1.11 _ARRAY_VALTYPE => '*default',
32 wakaba 1.9 _HASH_NAME => '',
33 wakaba 1.14 _METHODS => [qw|as_plain_string value_append|],
34 wakaba 1.11 _MEMBERS => [qw|field_body|],
35 wakaba 1.14 _VALTYPE_DEFAULT => '*default',
36 wakaba 1.10 by => 'index', ## (Reserved for method level option)
37 wakaba 1.9 dont_croak => 0, ## Don't die unless very very fatal error
38     encoding_after_encode => '*default',
39     encoding_before_decode => '*default',
40     field_param_name => '',
41     field_name => 'x-structured',
42 wakaba 1.14 #field_ns => '',
43 wakaba 1.9 format => 'mail-rfc2822',
44     hook_encode_string => #sub {shift; (value => shift, @_)},
45     \&Message::Util::encode_header_string,
46     hook_decode_string => #sub {shift; (value => shift, @_)},
47     \&Message::Util::decode_header_string,
48     #name ## Reserved for method level option
49     #parse ## Reserved for method level option
50     parse_all => 0,
51     prepend => 0, ## (Reserved for method level option)
52     value_type => {'*default' => [':none:']},
53 wakaba 1.11 );
54     sub _init ($;%) {
55     my $self = shift;
56     my %options = @_;
57     $self->{option} = Message::Util::make_clone (\%DEFAULT);
58 wakaba 1.5 $self->{field_body} = '';
59    
60     for my $name (keys %options) {
61     if (substr ($name, 0, 1) eq '-') {
62     $self->{option}->{substr ($name, 1)} = $options{$name};
63     } elsif (lc $name eq 'body') {
64     $self->{field_body} = $options{$name};
65     }
66     }
67 wakaba 1.13 $self->{comment} = [];
68 wakaba 1.5 }
69 wakaba 1.3
70 wakaba 1.5 =item Message::Field::Structured->new ([%options])
71 wakaba 1.1
72 wakaba 1.5 Constructs a new C<Message::Field::Structured> object. You might pass some
73     options as parameters to the constructor.
74 wakaba 1.1
75     =cut
76    
77 wakaba 1.2 sub new ($;%) {
78 wakaba 1.3 my $class = shift;
79 wakaba 1.5 my $self = bless {}, $class;
80     $self->_init (@_);
81 wakaba 1.3 $self;
82 wakaba 1.1 }
83    
84 wakaba 1.5 =item Message::Field::Structured->parse ($field-body, [%options])
85 wakaba 1.1
86 wakaba 1.5 Constructs a new C<Message::Field::Structured> object with
87     given field body. You might pass some options as parameters to the constructor.
88 wakaba 1.1
89     =cut
90    
91 wakaba 1.2 sub parse ($$;%) {
92 wakaba 1.3 my $class = shift;
93 wakaba 1.5 my $self = bless {}, $class;
94     $self->_init (@_);
95     #my $field_body = $self->Message::Util::decode_qcontent (shift);
96     $self->{field_body} = shift; #$field_body;
97 wakaba 1.1 $self;
98     }
99    
100 wakaba 1.5 =back
101    
102 wakaba 1.9 =cut
103    
104     ## Template procedures for array/hash fields
105     ## (As bare Message::Field::Structured module,
106     ## these shall not be used.)
107    
108     sub add ($$$%) {
109     my $self = shift;
110    
111     my $array = $self->{option}->{_ARRAY_NAME};
112     if ($array) {
113    
114     ## --- field is non-named value list (i.e. not hash)
115    
116     ## Options
117     my %option = %{$self->{option}};
118     if (ref $_[0] eq 'HASH') {
119     my $option = shift (@_);
120     for (keys %$option) {my $n = $_; $n =~ s/^-//; $option{$n} = $$option{$_}}
121     }
122 wakaba 1.11 $option{parse} = 1 if defined wantarray && !defined $option{parse};
123     $option{parse} = 1 if $option{parse_all} && !defined $option{parse};
124 wakaba 1.9
125     ## Additional items
126     my $avalue;
127     for (@_) {
128 wakaba 1.11 local $option{parse} = $option{parse};
129 wakaba 1.14 my $ok;
130     ($ok, undef, $avalue) = $self->_add_array_check ($_, \%option);
131 wakaba 1.9 if ($ok) {
132 wakaba 1.11 $avalue = $self->_parse_value
133     ($option{_ARRAY_VALTYPE} => $avalue) if $option{parse};
134 wakaba 1.9 if ($option{prepend}) {
135     unshift @{$self->{$array}}, $avalue;
136     } else {
137     push @{$self->{$array}}, $avalue;
138     }
139     }
140     }
141 wakaba 1.14 $self->_add_return_value (\$avalue, \%option);
142     ## Return last added value if necessary.
143 wakaba 1.9
144     } else {
145     $array = $self->{option}->{_HASH_NAME};
146    
147     ## --- field is not list
148    
149     unless ($array) {
150     my %option = @_;
151     return if $option{-dont_croak};
152     Carp::croak q{add: Method not available for this module};
153     }
154    
155     ## --- field is named value list (i.e. hash)
156    
157     ## Options
158     my %p = @_; my %option = %{$self->{option}};
159     for (grep {/^-/} keys %p) {$option{substr ($_, 1)} = $p{$_}}
160     $option{parse} = 1 if defined wantarray && !defined $option{parse};
161 wakaba 1.11 $option{parse} = 1 if $option{parse_all} && !defined $option{parse};
162 wakaba 1.9
163     ## Additional items
164     my $avalue;
165     while (my ($name => $value) = splice (@_, 0, 2)) {
166     next if $name =~ /^-/; $name =~ s/^\\//;
167 wakaba 1.14 $name =~ tr/_/-/ if $option{translate_underscore};
168 wakaba 1.9
169     my $ok;
170 wakaba 1.11 local $option{parse} = $option{parse};
171 wakaba 1.10 ($ok, $name, $avalue) = $self->_add_hash_check ($name => $value, \%option);
172 wakaba 1.9 if ($ok) {
173 wakaba 1.10 $avalue = $self->_parse_value ($name => $avalue) if $option{parse};
174 wakaba 1.9 if ($option{prepend}) {
175     unshift @{$self->{$array}}, $avalue;
176     } else {
177     push @{$self->{$array}}, $avalue;
178     }
179     }
180     }
181 wakaba 1.14 $self->_add_return_value (\$avalue, \%option);
182     ## Return last added value if necessary.
183 wakaba 1.9 }
184     }
185    
186     sub _add_array_check ($$\%) {
187     shift; 1, $_[0] => $_[0];
188     }
189     sub _add_hash_check ($$$\%) {
190     shift; 1, $_[0] => [@_[0,1]];
191     }
192 wakaba 1.14 ## Returns returned item value \$item-value, \%option
193     sub _add_return_value ($\$\%) {
194     $_[1];
195     }
196 wakaba 1.9
197     sub replace ($$$%) {
198     my $self = shift;
199    
200     $self->_replace_cleaning;
201     my $array = $self->{option}->{_ARRAY_NAME};
202     if ($array) {
203    
204     ## --- field is non-named value list (i.e. not hash)
205    
206     ## Options
207     my %option = %{$self->{option}};
208     if (ref $_[0] eq 'HASH') {
209     my $option = shift (@_);
210     for (keys %$option) {my $n = $_; $n =~ s/^-//; $option{$n} = $$option{$_}}
211     }
212 wakaba 1.11 $option{parse} = 1 if defined wantarray && !defined $option{parse};
213     $option{parse} = 1 if $option{parse_all} && !defined $option{parse};
214 wakaba 1.9
215     ## Additional items
216     my ($avalue, %replace);
217     for (@_) {
218 wakaba 1.11 local $option{parse} = $option{parse};
219 wakaba 1.9 my ($ok, $aname);
220     ($ok, $aname => $avalue)
221     = $self->_replace_array_check ($_, \%option);
222     if ($ok) {
223 wakaba 1.11 $avalue = $self->_parse_value
224     ($option{_ARRAY_VALTYPE} => $avalue) if $option{parse};
225 wakaba 1.9 $replace{$aname} = $avalue;
226     }
227     }
228     for (@{$self->{$array}}) {
229     my ($v) = $self->_replace_array_shift (\%replace => $_, \%option);
230     if (defined $v) {
231     $_ = $v;
232     }
233     }
234     for (keys %replace) {
235     if ($option{prepend}) {
236     unshift @{$self->{$array}}, $replace{$_};
237     } else {
238     push @{$self->{$array}}, $replace{$_};
239     }
240     }
241 wakaba 1.14 $self->_replace_return_value (\$avalue, \%option);
242     ## Return last added value if necessary.
243 wakaba 1.9
244     } else {
245     $array = $self->{option}->{_HASH_NAME};
246    
247     ## --- field is not list
248    
249     unless ($array) {
250     my %option = @_;
251     return if $option{-dont_croak};
252     Carp::croak q{replace: Method not available for this module};
253     }
254    
255     ## --- field is named value list (i.e. hash)
256    
257     ## Options
258     my %p = @_; my %option = %{$self->{option}};
259     for (grep {/^-/} keys %p) {$option{substr ($_, 1)} = $p{$_}}
260     $option{parse} = 1 if defined wantarray && !defined $option{parse};
261 wakaba 1.11 $option{parse} = 1 if $option{parse_all} && !defined $option{parse};
262 wakaba 1.9
263     ## Additional items
264     my ($avalue, %replace);
265     while (my ($name => $value) = splice (@_, 0, 2)) {
266     next if $name =~ /^-/; $name =~ s/^\\//;
267 wakaba 1.14 $name =~ tr/_/-/ if $option{translate_underscore};
268 wakaba 1.9
269     my ($ok, $aname);
270 wakaba 1.11 local $option{parse} = $option{parse};
271 wakaba 1.9 ($ok, $aname => $avalue)
272     = $self->_replace_hash_check ($name => $value, \%option);
273     if ($ok) {
274 wakaba 1.11 $avalue = $self->_parse_value ($name => $avalue) if $option{parse};
275 wakaba 1.9 $replace{$aname} = $avalue;
276     }
277     }
278     for (@{$self->{$array}}) {
279 wakaba 1.14 last unless keys %replace;
280 wakaba 1.9 my ($v) = $self->_replace_hash_shift (\%replace => $_, \%option);
281     if (defined $v) {
282     $_ = $v;
283     }
284     }
285     for (keys %replace) {
286     if ($option{prepend}) {
287     unshift @{$self->{$array}}, $replace{$_};
288     } else {
289     push @{$self->{$array}}, $replace{$_};
290     }
291     }
292 wakaba 1.14 $self->_replace_return_value (\$avalue, \%option);
293     ## Return last added value if necessary.
294 wakaba 1.9 }
295     }
296    
297     sub _replace_cleaning ($) {
298 wakaba 1.10 $_[0]->_delete_empty;
299 wakaba 1.9 }
300     sub _replace_array_check ($$\%) {
301     shift; 1, $_[0] => $_[0];
302     }
303     sub _replace_array_shift ($\%$\%) {
304     shift; my $r = shift; my $n = $_[0]->[0];
305     if ($$r{$n}) {
306     my $d = $$r{$n};
307     $$r{$n} = undef;
308     return $d;
309     }
310     undef;
311     }
312     sub _replace_hash_check ($$$\%) {
313     shift; 1, $_[0] => [@_[0,1]];
314     }
315     sub _replace_hash_shift ($\%$\%) {
316     shift; my $r = shift; my $n = $_[0]->[0];
317     if ($$r{$n}) {
318     my $d = $$r{$n};
319     $$r{$n} = undef;
320     return $d;
321     }
322     undef;
323     }
324 wakaba 1.14 ## Returns returned item value \$item-value, \%option
325     sub _replace_return_value ($\$\%) {
326     $_[1];
327     }
328 wakaba 1.9
329     sub count ($;%) {
330     my $self = shift; my %option = @_;
331     my $array = $self->{option}->{_ARRAY_NAME}
332     || $self->{option}->{_HASH_NAME};
333     unless ($array) {
334     return if $option{-dont_croak};
335     Carp::croak q{count: Method not available for this module};
336     }
337     $self->_count_cleaning;
338     return $self->_count_by_name ($array => \%option) if defined $option{-name};
339     $#{$self->{$array}} + 1;
340     }
341     sub _count_cleaning ($) {
342 wakaba 1.10 $_[0]->_delete_empty;
343 wakaba 1.9 }
344     sub _count_by_name ($$\%) {
345     # my $self = shift;
346     # my ($array, $option) = @_;
347     # my $name = $self->_n11n_*name* ($$option{-name});
348     # my @a = grep {$_->[0] eq $name} @{$self->{$array}};
349     # $#a + 1;
350     }
351    
352 wakaba 1.10 sub delete ($@) {
353     my $self = shift;
354     my %p; %p = %{shift (@_)} if ref $_[0] eq 'HASH';
355     my %option = %{$self->{option}};
356     for (grep {/^-/} keys %p) {$option{substr ($_, 1)} = $p{$_}}
357     my $array = $option{_ARRAY_NAME} || $option{_HASH_NAME};
358     unless ($array) {
359     return if $option{dont_croak};
360     Carp::croak q{delete: Method not available for this module};
361     }
362     if ($option{by} && $option{by} ne 'index') {
363     my %name; for (@_) {$name{$_} = 1}
364     for (@{$self->{$array}}) {
365     if ($self->_delete_match ($option{by}, \$_, \%name, \%option)) {
366     $_ = undef;
367     }
368     }
369     } else { ## by index
370     for (@_) {
371     $self->{$array}->[$_] = undef;
372     }
373     }
374     $self->_delete_cleaning;
375     }
376    
377     ## delete-by?, \$checked-item, \%delete-list, \%option
378     sub _delete_match ($$\$\%\%) {
379     0 #return 1 / 0
380     }
381    
382     sub _delete_cleaning ($) {
383     $_[0]->_delete_empty;
384     }
385    
386 wakaba 1.9 ## Delete empty items
387     sub _delete_empty ($) {
388 wakaba 1.11 my $self = shift;
389     my $array = $self->{option}->{_ARRAY_NAME} || $self->{option}->{_HASH_NAME};
390     $self->{$array} = [grep {length $_} @{$self->{$array}}] if $array;
391 wakaba 1.9 }
392    
393 wakaba 1.10 sub item ($$;%) {
394     my $self = shift;
395 wakaba 1.11 my ($name, %p) = (shift, @_); ## BUG: don't support -by
396 wakaba 1.10 return $self->replace ($name => $p{-value}, @_) if defined $p{-value};
397     my %option = %{$self->{option}};
398 wakaba 1.11 $option{new_item_unless_exist} = 1;
399 wakaba 1.10 for (grep {/^-/} keys %p) {$option{substr ($_, 1)} = $p{$_}}
400     my $array = $option{_ARRAY_NAME} || $option{_HASH_NAME};
401     unless ($array) {
402     return if $option{dont_croak};
403     Carp::croak q{item: Method not available for this module};
404     }
405 wakaba 1.11 my @r;
406 wakaba 1.10 if ($option{by} eq 'index') {
407     for ($self->{$array}->[$name]) {
408     return $self->_item_return_value (\$_, \%option);
409     }
410     } else {
411     for (@{$self->{$array}}) {
412     if ($self->_item_match ($option{by}, \$_, {$name => 1}, \%option)) {
413     if (wantarray) {
414     push @r, $self->_item_return_value (\$_, \%option);
415     } else {
416     return $self->_item_return_value (\$_, \%option);
417     }
418     }
419     }
420     }
421 wakaba 1.11 if (@r == 0 && $option{new_item_unless_exist}) {
422     my $v = $self->_item_new_value ($name, \%option);
423     if (defined $v) {
424     if ($option{prepend}) {
425     unshift @{$self->{$array}}, $v;
426     } else {
427     push @{$self->{$array}}, $v;
428     }
429     return $self->_item_return_value (\$v, \%option);
430     }
431     }
432     return undef unless wantarray;
433     @r;
434 wakaba 1.10 }
435    
436 wakaba 1.14 sub item_exist ($$;%) {
437     my $self = shift;
438     my ($name, %p) = (shift, @_);
439     my %option = %{$self->{option}};
440     for (grep {/^-/} keys %p) {$option{substr ($_, 1)} = $p{$_}}
441     my $array = $option{_ARRAY_NAME} || $option{_HASH_NAME};
442     unless ($array) {
443     return if $option{dont_croak};
444     Carp::croak q{item-exist: Method not available for this module};
445     }
446     my @r;
447     if ($option{by} eq 'index') {
448     return 1 if ref $self->{$array}->[$name];
449     } else {
450     for (@{$self->{$array}}) {
451     if ($self->_item_match ($option{by}, \$_, {$name => 1}, \%option)) {
452     return 1;
453     }
454     }
455     }
456     0;
457     }
458    
459 wakaba 1.10 ## item-by?, \$checked-item, {item-key => 1}, \%option
460     sub _item_match ($$\$\%\%) {
461     0 #return 1 / 0
462     }
463    
464     ## Returns returned item value \$item-value, \%option
465     sub _item_return_value ($\$\%) {
466 wakaba 1.11 $_[1];
467     }
468    
469     ## Returns returned (new created) item value $name, \%option
470     sub _item_new_value ($$\%) {
471     $_[1];
472 wakaba 1.10 }
473    
474 wakaba 1.9 ## $self->_parse_value ($type, $value);
475     sub _parse_value ($$$) {
476     my $self = shift;
477 wakaba 1.14 my $name = shift;
478 wakaba 1.9 my $value = shift;
479     return $value if ref $value;
480 wakaba 1.14 my $handler = $self->{option}->{value_type}->{$name}
481     || $self->{option}->{value_type}->{$self->{option}->{_VALTYPE_DEFAULT}};
482     if (ref $handler eq 'CODE') {
483     $handler = &$handler ($self);
484     }
485     my $vtype = $handler->[0];
486     my %vopt = (
487     -format => $self->{option}->{format},
488     -field_ns => $self->{option}->{field_ns},
489     -field_name => $self->{option}->{field_name},
490     -field_param_name => $name,
491     -parse_all => $self->{option}->{parse_all},
492     );
493     ## Media type specified option/parameters
494     if (ref $handler->[1] eq 'HASH') {
495     for (keys %{$handler->[1]}) {
496     $vopt{$_} = ${$handler->[1]}{$_};
497     }
498     }
499     ## Inherited options
500     if (ref $handler->[2] eq 'ARRAY') {
501     for (@{$handler->[2]}) {
502     $vopt{'-'.$_} = $self->{option}->{$_};
503     }
504     }
505    
506 wakaba 1.9 if ($vtype eq ':none:') {
507     return $value;
508     } elsif (defined $value) {
509     eval "require $vtype" or Carp::croak qq{<parse>: $vtype: Can't load package: $@};
510 wakaba 1.14 return $vtype->parse ($value, %vopt);
511 wakaba 1.9 } else {
512     eval "require $vtype" or Carp::croak qq{<parse>: $vtype: Can't load package: $@};
513 wakaba 1.14 return $vtype->new (%vopt);
514 wakaba 1.9 }
515     }
516    
517 wakaba 1.11 ## comments
518    
519    
520     sub comment_add ($@) {
521     my $self = shift;
522     my $array = 'comment';
523     ## Options
524     my %option = %{$self->{option}};
525     if (ref $_[0] eq 'HASH') {
526     my $option = shift (@_);
527     for (keys %$option) {my $n = $_; $n =~ s/^-//; $option{$n} = $$option{$_}}
528     }
529    
530     ## Additional items
531     if ($option{prepend}) {
532     unshift @{$self->{$array}}, reverse @_;
533     } else {
534     push @{$self->{$array}}, @_;
535     }
536     }
537    
538     sub comment_count ($) {
539     my $self = shift;
540     $self->_comment_cleaning;
541     $#{$self->{comment}} + 1;
542     }
543    
544     sub comment_delete ($@) {
545     my $self = shift;
546     #my %p; %p = %{shift (@_)} if ref $_[0] eq 'HASH';
547     #my %option = %{$self->{option}};
548     #for (grep {/^-/} keys %p) {$option{substr ($_, 1)} = $p{$_}}
549     for (@_) {
550     $self->{comment}->[$_] = undef;
551     }
552     $self->_comment_cleaning;
553     }
554    
555     sub comment_item ($$) {
556     $_[0]->{comment}->[$_[1]];
557     }
558    
559     sub _comment_cleaning ($) {
560     my $self = shift;
561     $self->{comment} = [grep {length $_} @{$self->{comment}}];
562     }
563    
564     sub _comment_stringify ($\%) {
565     my $self = shift;
566 wakaba 1.15 my $option = shift;
567     $option->{_comment_min} ||= 0;
568     $option->{_comment_max} = $#{$self->{comment}} unless defined $option->{_comment_max};
569 wakaba 1.11 my @v;
570 wakaba 1.15 for (@{$self->{comment}}[$option->{_comment_min}..$option->{_comment_max}]) {
571 wakaba 1.11 push @v, '('. $self->Message::Util::encode_ccontent ($_) .')';
572     }
573     join ' ', @v;
574     }
575    
576 wakaba 1.14 sub scan ($&;%) {
577     my $self = shift;
578     my $sub = shift;
579 wakaba 1.10 my %p = @_; my %option = %{$self->{option}};
580     for (grep {/^-/} keys %p) {$option{substr ($_, 1)} = $p{$_}}
581     my $array = $self->{option}->{_ARRAY_NAME}
582     || $self->{option}->{_HASH_NAME};
583 wakaba 1.14 my @param = $self->_scan_sort (\@{$self->{$array}});
584     #my $sort = $option{sort};
585     #@param = sort $sort @param if ref $sort;
586 wakaba 1.10 for my $param (@param) {
587     &$sub($self, $param);
588     }
589     }
590    
591 wakaba 1.14 sub _scan_sort ($\@) {
592     #my $self = shift;
593     @{$_[1]};
594     }
595    
596 wakaba 1.5 =head1 METHODS
597    
598     =over 4
599    
600     =item $self->stringify ([%options])
601 wakaba 1.1
602 wakaba 1.5 Returns field body as a string. Returned string is encoded,
603     quoted if necessary (by C<hook_encode_string>).
604 wakaba 1.1
605     =cut
606    
607 wakaba 1.7 sub stringify ($;%) {
608 wakaba 1.1 my $self = shift;
609 wakaba 1.5 #$self->Message::Util::encode_qcontent ($self->{field_body});
610     $self->{field_body};
611 wakaba 1.1 }
612 wakaba 1.5 *as_string = \&stringify;
613 wakaba 1.1
614 wakaba 1.5 =item $self->as_plain_string
615 wakaba 1.1
616 wakaba 1.5 Returns field body as a string. Returned string is not encoded
617     or quoted, i.e. internal/bare coded string. This string
618     may be unable to use as field body content. (Its I<structures>
619     such as C<comment> and C<quoted-string> are lost.)
620 wakaba 1.1
621     =cut
622    
623     sub as_plain_string ($) {
624     my $self = shift;
625 wakaba 1.5 my $s = $self->Message::Util::decode_qcontent ($self->{field_body});
626     Message::Util::unquote_quoted_string (Message::Util::unquote_ccontent ($s));
627 wakaba 1.1 }
628 wakaba 1.4
629 wakaba 1.5 =item $self->option ( $option-name / $option-name, $option-value, ...)
630 wakaba 1.4
631 wakaba 1.5 If @_ == 1, returns option value. Else...
632 wakaba 1.4
633 wakaba 1.5 Set option value. You can pass multiple option name-value pair
634     as parameter. Example:
635 wakaba 1.1
636 wakaba 1.5 $msg->option (format => 'mail-rfc822',
637     capitalize => 0);
638     print $msg->option ('format'); ## mail-rfc822
639 wakaba 1.1
640     =cut
641    
642 wakaba 1.5 sub option ($@) {
643 wakaba 1.1 my $self = shift;
644 wakaba 1.5 if (@_ == 1) {
645     return $self->{option}->{ $_[0] };
646     }
647 wakaba 1.14 my %option = @_;
648 wakaba 1.5 while (my ($name, $value) = splice (@_, 0, 2)) {
649 wakaba 1.14 $self->{option}->{$name} = $value;
650     }
651     if ($option{-recursive}) {
652     $self->_option_recursive (\%option);
653 wakaba 1.5 }
654 wakaba 1.12 $self;
655 wakaba 1.1 }
656    
657 wakaba 1.14 ## $self->_option_recursive (\%argv)
658     sub _option_recursive ($\%) {}
659    
660 wakaba 1.9 ## TODO: multiple value-type support
661     sub value_type ($;$$%) {
662     my $self = shift;
663 wakaba 1.14 my $name = shift || $self->{option}->{_VALTYPE_DEFAULT};
664 wakaba 1.9 my $new_value_type = shift;
665     if ($new_value_type) {
666     $self->{option}->{value_type}->{$name} = []
667     unless ref $self->{option}->{value_type}->{$name};
668     $self->{option}->{value_type}->{$name}->[0] = $new_value_type;
669     }
670     if (ref $self->{option}->{value_type}->{$name}) {
671     $self->{option}->{value_type}->{$name}->[0]
672 wakaba 1.14 || $self->{option}->{value_type}->{$self->{option}->{_VALTYPE_DEFAULT}}->[0];
673 wakaba 1.9 } else {
674 wakaba 1.14 $self->{option}->{value_type}->{$self->{option}->{_VALTYPE_DEFAULT}}->[0];
675 wakaba 1.9 }
676     }
677    
678 wakaba 1.5 =item $self->clone ()
679 wakaba 1.1
680 wakaba 1.5 Returns a copy of Message::Field::Structured object.
681 wakaba 1.1
682     =cut
683    
684 wakaba 1.5 sub clone ($) {
685 wakaba 1.1 my $self = shift;
686 wakaba 1.5 my $clone = ref($self)->new;
687 wakaba 1.9 $clone->{option} = Message::Util::make_clone ($self->{option});
688 wakaba 1.5 ## Common hash value (not used in this module)
689 wakaba 1.11 $self->_delete_empty;
690     $self->_comment_cleaning;
691     $clone->{value} = Message::Util::make_clone ($self->{value});
692     $clone->{comment} = Message::Util::make_clone ($self->{comment});
693     for (@{$self->{option}->{_MEMBERS}}) {
694     $clone->{$_} = Message::Util::make_clone ($self->{$_});
695     }
696 wakaba 1.5 $clone;
697 wakaba 1.1 }
698    
699 wakaba 1.8
700 wakaba 1.10 my %_method_default_list = qw(new 1 parse 1 stringify 1 option 1 clone 1 method_available 1);
701     sub method_available ($$) {
702     my $self = shift;
703     my $name = shift;
704     return 1 if $_method_default_list{$name};
705     for (@{$self->{option}->{_METHODS}}) {
706     return 1 if $_ eq $name;
707     }
708     0;
709     }
710 wakaba 1.5
711 wakaba 1.1 =head1 EXAMPLE
712    
713     use Message::Field::Structured;
714    
715     my $field_body = '"This is an example of <\"> (quotation mark)."
716     (Comment within \q\u\o\t\e\d\-\p\a\i\r\(\s\))';
717     my $field = Message::Field::Structured->parse ($field_body);
718    
719     print $field->as_plain_string;
720    
721 wakaba 1.5 =head1 SEE ALSO
722    
723     =over 4
724    
725     =item L<Message::Entity>, L<Message::Header>
726    
727     =item L<Message::Field::Unstructured>
728    
729     =item RFC 2822 E<lt>urn:ietf:rfc:2822E<gt>, usefor-article, HTTP/1.0, HTTP/1.1
730    
731     =back
732    
733 wakaba 1.1 =head1 LICENSE
734    
735     Copyright 2002 wakaba E<lt>w@suika.fam.cxE<gt>.
736    
737     This program is free software; you can redistribute it and/or modify
738     it under the terms of the GNU General Public License as published by
739     the Free Software Foundation; either version 2 of the License, or
740     (at your option) any later version.
741    
742     This program is distributed in the hope that it will be useful,
743     but WITHOUT ANY WARRANTY; without even the implied warranty of
744     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
745     GNU General Public License for more details.
746    
747     You should have received a copy of the GNU General Public License
748     along with this program; see the file COPYING. If not, write to
749     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
750     Boston, MA 02111-1307, USA.
751    
752     =head1 CHANGE
753    
754     See F<ChangeLog>.
755 wakaba 1.15 $Date: 2002/06/09 11:08:28 $
756 wakaba 1.1
757     =cut
758    
759     1;

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24