Upgrade to Encode 1.32, from Dan Kogai.
[p5sagit/p5-mst-13.2.git] / ext / Encode / lib / Encode / Encoder.pm
1 #
2 # $Id: Encoder.pm,v 0.2 2002/04/08 18:08:07 dankogai Exp $
3 #
4 package Encode::Encoder;
5 use strict;
6 use warnings;
7 our $VERSION = do { my @r = (q$Revision: 0.2 $ =~ /\d+/g); sprintf "%d."."%02d"  x $#r, @r };
8
9 require Exporter;
10 our @ISA = qw(Exporter);
11 our @EXPORT = qw ( encoder );
12
13 our $AUTOLOAD;
14 our $DEBUG = 0;
15 use Encode qw(encode decode find_encoding from_to);
16 use Carp;
17
18 sub new{
19     my ($class, $data, $encname) = @_;
20     unless($encname){
21         $encname = Encode::is_utf8($data) ? 'utf8' : '';
22     }else{
23         my $obj = find_encoding($encname) 
24             or croak __PACKAGE__, ": unknown encoding: $encname";
25         $encname = $obj->name;
26     }
27     my $self = {
28                 data     => $data,
29                 encoding => $encname,
30                };
31     bless $self => $class;
32 }
33
34 sub encoder{ __PACKAGE__->new(@_) }
35
36 sub data{
37     my ($self, $data) = shift;
38     if (defined $data){
39         $self->{data} = $data;
40         return $data;
41     }else{
42         return $self->{data};
43     }
44 }
45
46 sub encoding{
47     my ($self, $encname) = @_;
48     if ($encname){
49         my $obj = find_encoding($encname) 
50             or confess __PACKAGE__, ": unknown encoding: $encname";
51         $self->{encoding} = $obj->name;
52         return $self;
53     }else{
54         return $self->{encoding}
55     }
56 }
57
58 sub bytes {
59     my ($self, $encname) = @_;
60     $encname ||= $self->{encoding};
61     my $obj = find_encoding($encname) 
62             or confess __PACKAGE__, ": unknown encoding: $encname";
63     $self->{data} = $obj->decode($self->{data}, 1);
64     $self->{encoding} = '' ;
65     return $self;
66 }
67
68 sub DESTROY{ # defined so it won't autoload.
69     $DEBUG and warn shift;
70 }
71
72 sub AUTOLOAD {
73     my $self = shift;
74     my $type = ref($self)
75         or confess "$self is not an object";
76     my $myname = $AUTOLOAD;
77     $myname =~ s/.*://;   # strip fully-qualified portion
78     my $obj = find_encoding($myname) 
79             or confess __PACKAGE__, ": unknown encoding: $myname";
80     $DEBUG and warn $self->{encoding}, " => ", $obj->name;
81     if ($self->{encoding}){
82         from_to($self->{data}, $self->{encoding}, $obj->name, 1);
83     }else{
84         $self->{data} = $obj->encode($self->{data}, 1);
85     }
86     $self->{encoding} = $obj->name;
87     return $self;
88 }
89
90 use overload 
91     q("") => sub { $_[0]->{data} },
92     q(0+) => sub { use bytes (); bytes::length($_[0]->{data}) },
93     fallback => 1,
94     ;
95
96 1;
97 __END__
98
99 =head1 NAME
100
101 Encode::Encoder -- Object Oriented Encoder
102
103 =head1 SYNOPSIS
104        
105   use Encode::Encoder;
106   # Encode::encode("ISO-8859-1", $data); 
107   Encoder->new($data)->iso_8859_1; # OOP way
108   # shortcut
109   encoder($data)->iso_8859_1;
110   # you can stack them!
111   encoder($data)->iso_8859_1->base64;  # provided base64() is defined
112   # you can use it as a decoder as well
113   encoder($base64)->bytes('base64')->latin1;
114   # stringified
115   print encoder($data)->utf8->latin1;  # prints the string in latin1
116   # numified
117   encoder("\x{abcd}\x{ef}g")->utf8 == 6; # true. bytes::length($data)
118
119 =head1 ABSTRACT
120
121 B<Encode::Encoder> allows you to use Encode via OOP style.  This is
122 not only more intuitive than functional approach, but also handier
123 when you want to stack encodings.  Suppose you want your UTF-8 string
124 converted to Latin1 then Base64, you can simply say
125
126   my $base64 = encoder($utf8)->latin1->base64;
127
128 instead of
129
130   my $latin1 = encode("latin1", $utf8);
131   my $base64 = encode_base64($utf8);
132
133 or lazier and convolted
134
135   my $base64 = encode_base64(encode("latin1", $utf8));
136
137 =head1 Description
138
139 Here is how to use this module.
140
141 =over 4
142
143 =item *
144
145 There are at least two instance variable stored in hash reference,
146 {data} and {encoding}.
147
148 =item *
149
150 When there is no method, it takes the method name as the name of
151 encoding and encode instance I<data> with I<encoding>.  If successful,
152 instance I<encoding> is set accordingly.
153
154 =item *
155
156 You can retrieve the result via -E<gt>data but usually you don't have to 
157 because the stringify operator ("") is overridden to do exactly that.
158
159 =back
160
161 =head2 Predefined Methods
162
163 This module predefines the methods below;
164
165 =over 4
166
167 =item $e = Encode::Encoder-E<gt>new([$data, $encoding]);
168
169 returns the encoder object.  Its data is initialized with $data if
170 there, and its encoding is set to $encoding if there.
171
172 When $encoding is omitted, it defaults to utf8 if $data is already in
173 utf8 or "" (empty string) otherwise.
174
175 =item encoder()
176
177 is an alias of Encode::Encoder-E<gt>new().  This one is exported for
178 convenience.
179
180 =item $e-E<gt>data([$data])
181
182 when $data is present, sets instance data to $data and returns the
183 object itself. otherwise the current instance data is returned.
184
185 =item $e-E<gt>encoding([$encoding])
186
187 when $encoding is present, sets instance encoding to $encoding and
188 returns the object itself. otherwise the current instance encoding is
189 returned.
190
191 =item $e-E<gt>bytes([$encoding])
192
193 decodes instance data from $encoding, or instance encoding if omitted.
194 when the conversion is successful, the enstance encoding will be set
195 to "" . 
196
197 The name I<bytes> was deliberately picked to avoid namespace tainting
198 -- this module may be used as a base class so method names that appear
199 in Encode::Encoding are avoided.
200
201 =back
202
203 =head2 Example: base64 transcoder
204
205 This module is desined to work with L<Encode::Encoding>.
206 To make the Base64 transcorder example above really work, you should
207 write a module like this.
208
209   package Encode::Base64;
210   use base 'Encode::Encoding';
211   __PACKAGE__->Define('base64');
212   use MIME::Base64;
213   sub encode{ 
214       my ($obj, $data) = @_; 
215       return encode_base64($data);
216   }
217   sub decode{
218       my ($obj, $data) = @_; 
219       return decode_base64($data);
220   }
221   1;
222   __END__
223
224 And your caller module should be like this;
225
226   use Encode::Encoder;
227   use Encode::Base64;
228
229   # now you can really do the following
230
231   encoder($data)->iso_8859_1->base64;
232   encoder($base64)->bytes('base64')->latin1;
233
234 =head2 operator overloading
235
236 This module overloads two operators, stringify ("") and numify (0+).
237
238 Stringify dumps the data therein.
239
240 Numify returns the number of bytes therein.
241
242 They come in handy when you want to print or find the size of data.
243
244 =head1 SEE ALSO
245
246 L<Encode>
247 L<Encode::Encoding>
248
249 =cut