=head1 NAME Message::Field::Structured -- Perl module for unstructured header field bodies of the Internet message =cut package Message::Field::Unstructured; use strict; use vars qw(%DEFAULT $VERSION); $VERSION=do{my @r=(q$Revision: 1.8 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r}; require Message::Util; use overload '""' => sub { $_[0]->stringify }, '.=' => sub { $_[0]->value_append ($_[1]) }, #'eq' => sub { $_[0]->{field_body} eq $_[1] }, #'ne' => sub { $_[0]->{field_body} ne $_[1] }, fallback => 1; ## Initialize of this class -- called by constructors %DEFAULT = ( _METHODS => [qw|value value_append|], _MEMBERS => [qw|_charset|], encoding_after_encode => '*default', encoding_before_decode => '*default', field_param_name => '', field_name => 'x-structured', #field_ns => '', format => 'mail-rfc2822', ## MIME charset name of '*default' charset header_default_charset => 'iso-2022-int-1', header_default_charset_input => 'iso-2022-int-1', hook_encode_string => #sub {shift; (value => shift, @_)}, \&Message::Util::encode_header_string, hook_decode_string => #sub {shift; (value => shift, @_)}, \&Message::Util::decode_header_string, internal_charset_name => 'utf-8', ); sub _init ($;%) { my $self = shift; my %options = @_; $self->{option} = Message::Util::make_clone (\%DEFAULT); $self->{value} = ''; for my $name (keys %options) { if (substr ($name, 0, 1) eq '-') { $self->{option}->{substr ($name, 1)} = $options{$name}; } elsif ($name eq 'body') { $self->{value} = $options{$name}; } } } =head1 CONSTRUCTORS The following methods construct new C objects: =over 4 =item Message::Field::Unstructured->new ([%options]) Constructs a new C object. You might pass some options as parameters to the constructor. =cut sub new ($;%) { my $class = shift; my $self = bless {}, $class; $self->_init (@_); $self; } =item Message::Field::Unstructured->parse ($field-body, [%options]) Constructs a new C object with given field body. You might pass some options as parameters to the constructor. Although name, this method doesn't parse C<$field-body> (first argument) since there is no need to parse unstructured field body:-) =cut sub parse ($$;%) { my $class = shift; my $field_body = shift; my $self = bless {}, $class; $self->_init (@_); my %s = &{$self->{option}->{hook_decode_string}} ($self, $field_body, type => 'text', charset => $self->{option}->{encoding_before_decode}, ); if ($s{charset}) { ## Convertion failed $self->{_charset} = $s{charset}; } elsif (!$s{success}) { $self->{_charset} = $self->{option}->{header_default_charset_input}; } $self->{value} = $s{value}; $self; } =back =head1 METHODS =over 4 =item $self->stringify ([%options]) Returns field body as a string. Returned string is encoded if necessary (by C). =cut sub stringify ($;%) { my $self = shift; my %o = @_; my %option = %{$self->{option}}; for (grep {/^-/} keys %o) {$option{substr ($_, 1)} = $o{$_}} if ($self->{_charset}) { $self->{value}; } else { my (%e) = &{$option{hook_encode_string}} ($self, $self->{value}, charset => $option{encoding_after_encode}, current_charset => $option{internal_charset}, type => 'text', ); $e{value}; } } *as_string = \&stringify; =item $self->value ([$new-value]) Set/gets current value of this field. Returned/given value should not be encoded (i.e. in internal code). =cut sub value ($;$) { my $self = shift; my $v = shift; if (defined $v) { $self->{value} = $v; } $self->{value}; } *as_plain_string = \&value; sub value_append ($$) { $_[0]->{field_body} .= $_[1]; } =item $self->option ( $option-name / $option-name, $option-value, ...) If @_ == 1, returns option value. Else... Set option value. You can pass multiple option name-value pair as parameter. Example: $msg->option (-format => 'mail-rfc822', -capitalize => 0); print $msg->option ('-format'); ## mail-rfc822 Note that introduction character, i.e. C<-> (HYPHEN-MINUS) is optional. You can also write as this: $msg->option (format => 'mail-rfc822', capitalize => 0); print $msg->option ('format'); ## mail-rfc822 =cut sub option ($@) { my $self = shift; if (@_ == 1) { return $self->{option}->{ $_[0] }; } my %option = @_; while (my ($name, $value) = splice (@_, 0, 2)) { $self->{option}->{$name} = $value; } if ($option{-recursive}) { $self->_option_recursive (\%option); } $self; } ## $self->_option_recursive (\%argv) sub _option_recursive ($\%) {} =item $self->clone () Returns a copy of Message::Field::Unstructured object. =cut sub clone ($) { my $self = shift; my $clone = ref ($self)->new; $clone->{option} = Message::Util::make_clone ($self->{option}); $clone->{value} = Message::Util::make_clone ($self->{value}); for (@{$self->{option}->{_MEMBERS}}) { $clone->{$_} = Message::Util::make_clone ($self->{$_}); } $clone; } my %_method_default_list = qw(new 1 parse 1 stringify 1 option 1 clone 1 method_available 1); sub method_available ($$) { my $self = shift; my $name = shift; return 1 if $_method_default_list{$name}; for (@{$self->{option}->{_METHODS}}) { return 1 if $_ eq $name; } 0; } =head1 SEE ALSO =over 4 =item L, L =item L =item RFC 2822 Eurn:ietf:rfc:2822E, usefor-article, HTTP/1.0, HTTP/1.1 =back =head1 LICENSE Copyright 2002 wakaba Ew@suika.fam.cxE. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. =head1 CHANGE See F. $Date: 2002/08/01 09:19:46 $ =cut 1;