1N/A#
1N/A# $Id: Encoder.pm,v 0.7 2003/07/08 21:52:14 dankogai Exp $
1N/A#
1N/Apackage Encode::Encoder;
1N/Ause strict;
1N/Ause warnings;
1N/Aour $VERSION = do { my @r = (q$Revision: 0.7 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r };
1N/A
1N/Arequire Exporter;
1N/Aour @ISA = qw(Exporter);
1N/Aour @EXPORT_OK = qw ( encoder );
1N/A
1N/Aour $AUTOLOAD;
1N/Asub DEBUG () { 0 }
1N/Ause Encode qw(encode decode find_encoding from_to);
1N/Ause Carp;
1N/A
1N/Asub new{
1N/A my ($class, $data, $encname) = @_;
1N/A unless($encname){
1N/A $encname = Encode::is_utf8($data) ? 'utf8' : '';
1N/A }else{
1N/A my $obj = find_encoding($encname)
1N/A or croak __PACKAGE__, ": unknown encoding: $encname";
1N/A $encname = $obj->name;
1N/A }
1N/A my $self = {
1N/A data => $data,
1N/A encoding => $encname,
1N/A };
1N/A bless $self => $class;
1N/A}
1N/A
1N/Asub encoder{ __PACKAGE__->new(@_) }
1N/A
1N/Asub data{
1N/A my ($self, $data) = @_;
1N/A if (defined $data){
1N/A $self->{data} = $data;
1N/A return $data;
1N/A }else{
1N/A return $self->{data};
1N/A }
1N/A}
1N/A
1N/Asub encoding{
1N/A my ($self, $encname) = @_;
1N/A if ($encname){
1N/A my $obj = find_encoding($encname)
1N/A or confess __PACKAGE__, ": unknown encoding: $encname";
1N/A $self->{encoding} = $obj->name;
1N/A return $self;
1N/A }else{
1N/A return $self->{encoding}
1N/A }
1N/A}
1N/A
1N/Asub bytes {
1N/A my ($self, $encname) = @_;
1N/A $encname ||= $self->{encoding};
1N/A my $obj = find_encoding($encname)
1N/A or confess __PACKAGE__, ": unknown encoding: $encname";
1N/A $self->{data} = $obj->decode($self->{data}, 1);
1N/A $self->{encoding} = '' ;
1N/A return $self;
1N/A}
1N/A
1N/Asub DESTROY{ # defined so it won't autoload.
1N/A DEBUG and warn shift;
1N/A}
1N/A
1N/Asub AUTOLOAD {
1N/A my $self = shift;
1N/A my $type = ref($self)
1N/A or confess "$self is not an object";
1N/A my $myname = $AUTOLOAD;
1N/A $myname =~ s/.*://; # strip fully-qualified portion
1N/A my $obj = find_encoding($myname)
1N/A or confess __PACKAGE__, ": unknown encoding: $myname";
1N/A DEBUG and warn $self->{encoding}, " => ", $obj->name;
1N/A if ($self->{encoding}){
1N/A from_to($self->{data}, $self->{encoding}, $obj->name, 1);
1N/A }else{
1N/A $self->{data} = $obj->encode($self->{data}, 1);
1N/A }
1N/A $self->{encoding} = $obj->name;
1N/A return $self;
1N/A}
1N/A
1N/Ause overload
1N/A q("") => sub { $_[0]->{data} },
1N/A q(0+) => sub { use bytes (); bytes::length($_[0]->{data}) },
1N/A fallback => 1,
1N/A ;
1N/A
1N/A1;
1N/A__END__
1N/A
1N/A=head1 NAME
1N/A
1N/AEncode::Encoder -- Object Oriented Encoder
1N/A
1N/A=head1 SYNOPSIS
1N/A
1N/A use Encode::Encoder;
1N/A # Encode::encode("ISO-8859-1", $data);
1N/A Encode::Encoder->new($data)->iso_8859_1; # OOP way
1N/A # shortcut
1N/A use Encode::Encoder qw(encoder);
1N/A encoder($data)->iso_8859_1;
1N/A # you can stack them!
1N/A encoder($data)->iso_8859_1->base64; # provided base64() is defined
1N/A # you can use it as a decoder as well
1N/A encoder($base64)->bytes('base64')->latin1;
1N/A # stringified
1N/A print encoder($data)->utf8->latin1; # prints the string in latin1
1N/A # numified
1N/A encoder("\x{abcd}\x{ef}g")->utf8 == 6; # true. bytes::length($data)
1N/A
1N/A=head1 ABSTRACT
1N/A
1N/AB<Encode::Encoder> allows you to use Encode in an object-oriented
1N/Astyle. This is not only more intuitive than a functional approach,
1N/Abut also handier when you want to stack encodings. Suppose you want
1N/Ayour UTF-8 string converted to Latin1 then Base64: you can simply say
1N/A
1N/A my $base64 = encoder($utf8)->latin1->base64;
1N/A
1N/Ainstead of
1N/A
1N/A my $latin1 = encode("latin1", $utf8);
1N/A my $base64 = encode_base64($utf8);
1N/A
1N/Aor the lazier and more convoluted
1N/A
1N/A my $base64 = encode_base64(encode("latin1", $utf8));
1N/A
1N/A=head1 Description
1N/A
1N/AHere is how to use this module.
1N/A
1N/A=over 4
1N/A
1N/A=item *
1N/A
1N/AThere are at least two instance variables stored in a hash reference,
1N/A{data} and {encoding}.
1N/A
1N/A=item *
1N/A
1N/AWhen there is no method, it takes the method name as the name of the
1N/Aencoding and encodes the instance I<data> with I<encoding>. If successful,
1N/Athe instance I<encoding> is set accordingly.
1N/A
1N/A=item *
1N/A
1N/AYou can retrieve the result via -E<gt>data but usually you don't have to
1N/Abecause the stringify operator ("") is overridden to do exactly that.
1N/A
1N/A=back
1N/A
1N/A=head2 Predefined Methods
1N/A
1N/AThis module predefines the methods below:
1N/A
1N/A=over 4
1N/A
1N/A=item $e = Encode::Encoder-E<gt>new([$data, $encoding]);
1N/A
1N/Areturns an encoder object. Its data is initialized with $data if
1N/Apresent, and its encoding is set to $encoding if present.
1N/A
1N/AWhen $encoding is omitted, it defaults to utf8 if $data is already in
1N/Autf8 or "" (empty string) otherwise.
1N/A
1N/A=item encoder()
1N/A
1N/Ais an alias of Encode::Encoder-E<gt>new(). This one is exported on demand.
1N/A
1N/A=item $e-E<gt>data([$data])
1N/A
1N/AWhen $data is present, sets the instance data to $data and returns the
1N/Aobject itself. Otherwise, the current instance data is returned.
1N/A
1N/A=item $e-E<gt>encoding([$encoding])
1N/A
1N/AWhen $encoding is present, sets the instance encoding to $encoding and
1N/Areturns the object itself. Otherwise, the current instance encoding is
1N/Areturned.
1N/A
1N/A=item $e-E<gt>bytes([$encoding])
1N/A
1N/Adecodes instance data from $encoding, or the instance encoding if
1N/Aomitted. If the conversion is successful, the instance encoding
1N/Awill be set to "".
1N/A
1N/AThe name I<bytes> was deliberately picked to avoid namespace tainting
1N/A-- this module may be used as a base class so method names that appear
1N/Ain Encode::Encoding are avoided.
1N/A
1N/A=back
1N/A
1N/A=head2 Example: base64 transcoder
1N/A
1N/AThis module is designed to work with L<Encode::Encoding>.
1N/ATo make the Base64 transcoder example above really work, you could
1N/Awrite a module like this:
1N/A
1N/A package Encode::Base64;
1N/A use base 'Encode::Encoding';
1N/A __PACKAGE__->Define('base64');
1N/A use MIME::Base64;
1N/A sub encode{
1N/A my ($obj, $data) = @_;
1N/A return encode_base64($data);
1N/A }
1N/A sub decode{
1N/A my ($obj, $data) = @_;
1N/A return decode_base64($data);
1N/A }
1N/A 1;
1N/A __END__
1N/A
1N/AAnd your caller module would be something like this:
1N/A
1N/A use Encode::Encoder;
1N/A use Encode::Base64;
1N/A
1N/A # now you can really do the following
1N/A
1N/A encoder($data)->iso_8859_1->base64;
1N/A encoder($base64)->bytes('base64')->latin1;
1N/A
1N/A=head2 Operator Overloading
1N/A
1N/AThis module overloads two operators, stringify ("") and numify (0+).
1N/A
1N/AStringify dumps the data inside the object.
1N/A
1N/ANumify returns the number of bytes in the instance data.
1N/A
1N/AThey come in handy when you want to print or find the size of data.
1N/A
1N/A=head1 SEE ALSO
1N/A
1N/AL<Encode>,
1N/AL<Encode::Encoding>
1N/A
1N/A=cut