/[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.16 - (hide annotations) (download)
Sun Jun 23 12:10:16 2002 UTC (22 years, 5 months ago) by wakaba
Branch: MAIN
Changes since 1.15: +15 -8 lines
2002-06-23  Wakaba <w@suika.fam.cx>

	* AngleQuoted.pm (%REG): Don't define regex locally.
	(Moved to Message::Util).
	* ContentType.pm, Date.pm, UA.pm,
	ValueParams.pm: Fix some codes not to be warned
	as 'Use of uninitialized value'.
	* Structured.pm 
	(header_default_charset, header_default_charset_input):
	New options.

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24