芝麻web文件管理V1.00
编辑当前文件:/home/conskgoa/doughi.co.uk/Encode.zip
PK #\ Encoder.pmnu [ # # $Id: Encoder.pm,v 2.3 2013/09/14 07:51:59 dankogai Exp $ # package Encode::Encoder; use strict; use warnings; our $VERSION = do { my @r = ( q$Revision: 2.3 $ =~ /\d+/g ); sprintf "%d." . "%02d" x $#r, @r }; require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw ( encoder ); our $AUTOLOAD; use constant DEBUG => !!$ENV{PERL_ENCODE_DEBUG}; use Encode qw(encode decode find_encoding from_to); use Carp; sub new { my ( $class, $data, $encname ) = @_; unless ($encname) { $encname = Encode::is_utf8($data) ? 'utf8' : ''; } else { my $obj = find_encoding($encname) or croak __PACKAGE__, ": unknown encoding: $encname"; $encname = $obj->name; } my $self = { data => $data, encoding => $encname, }; bless $self => $class; } sub encoder { __PACKAGE__->new(@_) } sub data { my ( $self, $data ) = @_; if ( defined $data ) { $self->{data} = $data; return $data; } else { return $self->{data}; } } sub encoding { my ( $self, $encname ) = @_; if ($encname) { my $obj = find_encoding($encname) or confess __PACKAGE__, ": unknown encoding: $encname"; $self->{encoding} = $obj->name; return $self; } else { return $self->{encoding}; } } sub bytes { my ( $self, $encname ) = @_; $encname ||= $self->{encoding}; my $obj = find_encoding($encname) or confess __PACKAGE__, ": unknown encoding: $encname"; $self->{data} = $obj->decode( $self->{data}, 1 ); $self->{encoding} = ''; return $self; } sub DESTROY { # defined so it won't autoload. DEBUG and warn shift; } sub AUTOLOAD { my $self = shift; my $type = ref($self) or confess "$self is not an object"; my $myname = $AUTOLOAD; $myname =~ s/.*://; # strip fully-qualified portion my $obj = find_encoding($myname) or confess __PACKAGE__, ": unknown encoding: $myname"; DEBUG and warn $self->{encoding}, " => ", $obj->name; if ( $self->{encoding} ) { from_to( $self->{data}, $self->{encoding}, $obj->name, 1 ); } else { $self->{data} = $obj->encode( $self->{data}, 1 ); } $self->{encoding} = $obj->name; return $self; } use overload q("") => sub { $_[0]->{data} }, q(0+) => sub { use bytes(); bytes::length( $_[0]->{data} ) }, fallback => 1, ; 1; __END__ =head1 NAME Encode::Encoder -- Object Oriented Encoder =head1 SYNOPSIS use Encode::Encoder; # Encode::encode("ISO-8859-1", $data); Encode::Encoder->new($data)->iso_8859_1; # OOP way # shortcut use Encode::Encoder qw(encoder); encoder($data)->iso_8859_1; # you can stack them! encoder($data)->iso_8859_1->base64; # provided base64() is defined # you can use it as a decoder as well encoder($base64)->bytes('base64')->latin1; # stringified print encoder($data)->utf8->latin1; # prints the string in latin1 # numified encoder("\x{abcd}\x{ef}g")->utf8 == 6; # true. bytes::length($data) =head1 ABSTRACT B
allows you to use Encode in an object-oriented style. This is not only more intuitive than a functional approach, but also handier when you want to stack encodings. Suppose you want your UTF-8 string converted to Latin1 then Base64: you can simply say my $base64 = encoder($utf8)->latin1->base64; instead of my $latin1 = encode("latin1", $utf8); my $base64 = encode_base64($utf8); or the lazier and more convoluted my $base64 = encode_base64(encode("latin1", $utf8)); =head1 Description Here is how to use this module. =over 4 =item * There are at least two instance variables stored in a hash reference, {data} and {encoding}. =item * When there is no method, it takes the method name as the name of the encoding and encodes the instance I
with I
. If successful, the instance I
is set accordingly. =item * You can retrieve the result via -E
data but usually you don't have to because the stringify operator ("") is overridden to do exactly that. =back =head2 Predefined Methods This module predefines the methods below: =over 4 =item $e = Encode::Encoder-E
new([$data, $encoding]); returns an encoder object. Its data is initialized with $data if present, and its encoding is set to $encoding if present. When $encoding is omitted, it defaults to utf8 if $data is already in utf8 or "" (empty string) otherwise. =item encoder() is an alias of Encode::Encoder-E
new(). This one is exported on demand. =item $e-E
data([$data]) When $data is present, sets the instance data to $data and returns the object itself. Otherwise, the current instance data is returned. =item $e-E
encoding([$encoding]) When $encoding is present, sets the instance encoding to $encoding and returns the object itself. Otherwise, the current instance encoding is returned. =item $e-E
bytes([$encoding]) decodes instance data from $encoding, or the instance encoding if omitted. If the conversion is successful, the instance encoding will be set to "". The name I
was deliberately picked to avoid namespace tainting -- this module may be used as a base class so method names that appear in Encode::Encoding are avoided. =back =head2 Example: base64 transcoder This module is designed to work with L
. To make the Base64 transcoder example above really work, you could write a module like this: package Encode::Base64; use parent 'Encode::Encoding'; __PACKAGE__->Define('base64'); use MIME::Base64; sub encode{ my ($obj, $data) = @_; return encode_base64($data); } sub decode{ my ($obj, $data) = @_; return decode_base64($data); } 1; __END__ And your caller module would be something like this: use Encode::Encoder; use Encode::Base64; # now you can really do the following encoder($data)->iso_8859_1->base64; encoder($base64)->bytes('base64')->latin1; =head2 Operator Overloading This module overloads two operators, stringify ("") and numify (0+). Stringify dumps the data inside the object. Numify returns the number of bytes in the instance data. They come in handy when you want to print or find the size of data. =head1 SEE ALSO L
, L
=cut PK #\ǺC _T.e2xnu [ use strict; # Adjust the number here! use Test::More tests => 2; BEGIN { use_ok('Encode'); use_ok('Encode::$_Name_'); } # Add more test here! PK #\'lg. g. GSM0338.pmnu [ # # $Id: GSM0338.pm,v 2.7 2017/06/10 17:23:50 dankogai Exp $ # package Encode::GSM0338; use strict; use warnings; use Carp; use vars qw($VERSION); $VERSION = do { my @r = ( q$Revision: 2.7 $ =~ /\d+/g ); sprintf "%d." . "%02d" x $#r, @r }; use Encode qw(:fallbacks); use parent qw(Encode::Encoding); __PACKAGE__->Define('gsm0338'); sub needs_lines { 1 } sub perlio_ok { 0 } use utf8; our %UNI2GSM = ( "\x{0040}" => "\x00", # COMMERCIAL AT "\x{000A}" => "\x0A", # LINE FEED "\x{000C}" => "\x1B\x0A", # FORM FEED "\x{000D}" => "\x0D", # CARRIAGE RETURN "\x{0020}" => "\x20", # SPACE "\x{0021}" => "\x21", # EXCLAMATION MARK "\x{0022}" => "\x22", # QUOTATION MARK "\x{0023}" => "\x23", # NUMBER SIGN "\x{0024}" => "\x02", # DOLLAR SIGN "\x{0025}" => "\x25", # PERCENT SIGN "\x{0026}" => "\x26", # AMPERSAND "\x{0027}" => "\x27", # APOSTROPHE "\x{0028}" => "\x28", # LEFT PARENTHESIS "\x{0029}" => "\x29", # RIGHT PARENTHESIS "\x{002A}" => "\x2A", # ASTERISK "\x{002B}" => "\x2B", # PLUS SIGN "\x{002C}" => "\x2C", # COMMA "\x{002D}" => "\x2D", # HYPHEN-MINUS "\x{002E}" => "\x2E", # FULL STOP "\x{002F}" => "\x2F", # SOLIDUS "\x{0030}" => "\x30", # DIGIT ZERO "\x{0031}" => "\x31", # DIGIT ONE "\x{0032}" => "\x32", # DIGIT TWO "\x{0033}" => "\x33", # DIGIT THREE "\x{0034}" => "\x34", # DIGIT FOUR "\x{0035}" => "\x35", # DIGIT FIVE "\x{0036}" => "\x36", # DIGIT SIX "\x{0037}" => "\x37", # DIGIT SEVEN "\x{0038}" => "\x38", # DIGIT EIGHT "\x{0039}" => "\x39", # DIGIT NINE "\x{003A}" => "\x3A", # COLON "\x{003B}" => "\x3B", # SEMICOLON "\x{003C}" => "\x3C", # LESS-THAN SIGN "\x{003D}" => "\x3D", # EQUALS SIGN "\x{003E}" => "\x3E", # GREATER-THAN SIGN "\x{003F}" => "\x3F", # QUESTION MARK "\x{0041}" => "\x41", # LATIN CAPITAL LETTER A "\x{0042}" => "\x42", # LATIN CAPITAL LETTER B "\x{0043}" => "\x43", # LATIN CAPITAL LETTER C "\x{0044}" => "\x44", # LATIN CAPITAL LETTER D "\x{0045}" => "\x45", # LATIN CAPITAL LETTER E "\x{0046}" => "\x46", # LATIN CAPITAL LETTER F "\x{0047}" => "\x47", # LATIN CAPITAL LETTER G "\x{0048}" => "\x48", # LATIN CAPITAL LETTER H "\x{0049}" => "\x49", # LATIN CAPITAL LETTER I "\x{004A}" => "\x4A", # LATIN CAPITAL LETTER J "\x{004B}" => "\x4B", # LATIN CAPITAL LETTER K "\x{004C}" => "\x4C", # LATIN CAPITAL LETTER L "\x{004D}" => "\x4D", # LATIN CAPITAL LETTER M "\x{004E}" => "\x4E", # LATIN CAPITAL LETTER N "\x{004F}" => "\x4F", # LATIN CAPITAL LETTER O "\x{0050}" => "\x50", # LATIN CAPITAL LETTER P "\x{0051}" => "\x51", # LATIN CAPITAL LETTER Q "\x{0052}" => "\x52", # LATIN CAPITAL LETTER R "\x{0053}" => "\x53", # LATIN CAPITAL LETTER S "\x{0054}" => "\x54", # LATIN CAPITAL LETTER T "\x{0055}" => "\x55", # LATIN CAPITAL LETTER U "\x{0056}" => "\x56", # LATIN CAPITAL LETTER V "\x{0057}" => "\x57", # LATIN CAPITAL LETTER W "\x{0058}" => "\x58", # LATIN CAPITAL LETTER X "\x{0059}" => "\x59", # LATIN CAPITAL LETTER Y "\x{005A}" => "\x5A", # LATIN CAPITAL LETTER Z "\x{005F}" => "\x11", # LOW LINE "\x{0061}" => "\x61", # LATIN SMALL LETTER A "\x{0062}" => "\x62", # LATIN SMALL LETTER B "\x{0063}" => "\x63", # LATIN SMALL LETTER C "\x{0064}" => "\x64", # LATIN SMALL LETTER D "\x{0065}" => "\x65", # LATIN SMALL LETTER E "\x{0066}" => "\x66", # LATIN SMALL LETTER F "\x{0067}" => "\x67", # LATIN SMALL LETTER G "\x{0068}" => "\x68", # LATIN SMALL LETTER H "\x{0069}" => "\x69", # LATIN SMALL LETTER I "\x{006A}" => "\x6A", # LATIN SMALL LETTER J "\x{006B}" => "\x6B", # LATIN SMALL LETTER K "\x{006C}" => "\x6C", # LATIN SMALL LETTER L "\x{006D}" => "\x6D", # LATIN SMALL LETTER M "\x{006E}" => "\x6E", # LATIN SMALL LETTER N "\x{006F}" => "\x6F", # LATIN SMALL LETTER O "\x{0070}" => "\x70", # LATIN SMALL LETTER P "\x{0071}" => "\x71", # LATIN SMALL LETTER Q "\x{0072}" => "\x72", # LATIN SMALL LETTER R "\x{0073}" => "\x73", # LATIN SMALL LETTER S "\x{0074}" => "\x74", # LATIN SMALL LETTER T "\x{0075}" => "\x75", # LATIN SMALL LETTER U "\x{0076}" => "\x76", # LATIN SMALL LETTER V "\x{0077}" => "\x77", # LATIN SMALL LETTER W "\x{0078}" => "\x78", # LATIN SMALL LETTER X "\x{0079}" => "\x79", # LATIN SMALL LETTER Y "\x{007A}" => "\x7A", # LATIN SMALL LETTER Z "\x{000C}" => "\x1B\x0A", # FORM FEED "\x{005B}" => "\x1B\x3C", # LEFT SQUARE BRACKET "\x{005C}" => "\x1B\x2F", # REVERSE SOLIDUS "\x{005D}" => "\x1B\x3E", # RIGHT SQUARE BRACKET "\x{005E}" => "\x1B\x14", # CIRCUMFLEX ACCENT "\x{007B}" => "\x1B\x28", # LEFT CURLY BRACKET "\x{007C}" => "\x1B\x40", # VERTICAL LINE "\x{007D}" => "\x1B\x29", # RIGHT CURLY BRACKET "\x{007E}" => "\x1B\x3D", # TILDE "\x{00A0}" => "\x1B", # NO-BREAK SPACE "\x{00A1}" => "\x40", # INVERTED EXCLAMATION MARK "\x{00A3}" => "\x01", # POUND SIGN "\x{00A4}" => "\x24", # CURRENCY SIGN "\x{00A5}" => "\x03", # YEN SIGN "\x{00A7}" => "\x5F", # SECTION SIGN "\x{00BF}" => "\x60", # INVERTED QUESTION MARK "\x{00C4}" => "\x5B", # LATIN CAPITAL LETTER A WITH DIAERESIS "\x{00C5}" => "\x0E", # LATIN CAPITAL LETTER A WITH RING ABOVE "\x{00C6}" => "\x1C", # LATIN CAPITAL LETTER AE "\x{00C9}" => "\x1F", # LATIN CAPITAL LETTER E WITH ACUTE "\x{00D1}" => "\x5D", # LATIN CAPITAL LETTER N WITH TILDE "\x{00D6}" => "\x5C", # LATIN CAPITAL LETTER O WITH DIAERESIS "\x{00D8}" => "\x0B", # LATIN CAPITAL LETTER O WITH STROKE "\x{00DC}" => "\x5E", # LATIN CAPITAL LETTER U WITH DIAERESIS "\x{00DF}" => "\x1E", # LATIN SMALL LETTER SHARP S "\x{00E0}" => "\x7F", # LATIN SMALL LETTER A WITH GRAVE "\x{00E4}" => "\x7B", # LATIN SMALL LETTER A WITH DIAERESIS "\x{00E5}" => "\x0F", # LATIN SMALL LETTER A WITH RING ABOVE "\x{00E6}" => "\x1D", # LATIN SMALL LETTER AE #"\x{00E7}" => "\x09", # LATIN SMALL LETTER C WITH CEDILLA "\x{00C7}" => "\x09", # LATIN CAPITAL LETTER C WITH CEDILLA "\x{00E8}" => "\x04", # LATIN SMALL LETTER E WITH GRAVE "\x{00E9}" => "\x05", # LATIN SMALL LETTER E WITH ACUTE "\x{00EC}" => "\x07", # LATIN SMALL LETTER I WITH GRAVE "\x{00F1}" => "\x7D", # LATIN SMALL LETTER N WITH TILDE "\x{00F2}" => "\x08", # LATIN SMALL LETTER O WITH GRAVE "\x{00F6}" => "\x7C", # LATIN SMALL LETTER O WITH DIAERESIS "\x{00F8}" => "\x0C", # LATIN SMALL LETTER O WITH STROKE "\x{00F9}" => "\x06", # LATIN SMALL LETTER U WITH GRAVE "\x{00FC}" => "\x7E", # LATIN SMALL LETTER U WITH DIAERESIS "\x{0393}" => "\x13", # GREEK CAPITAL LETTER GAMMA "\x{0394}" => "\x10", # GREEK CAPITAL LETTER DELTA "\x{0398}" => "\x19", # GREEK CAPITAL LETTER THETA "\x{039B}" => "\x14", # GREEK CAPITAL LETTER LAMDA "\x{039E}" => "\x1A", # GREEK CAPITAL LETTER XI "\x{03A0}" => "\x16", # GREEK CAPITAL LETTER PI "\x{03A3}" => "\x18", # GREEK CAPITAL LETTER SIGMA "\x{03A6}" => "\x12", # GREEK CAPITAL LETTER PHI "\x{03A8}" => "\x17", # GREEK CAPITAL LETTER PSI "\x{03A9}" => "\x15", # GREEK CAPITAL LETTER OMEGA "\x{20AC}" => "\x1B\x65", # EURO SIGN ); our %GSM2UNI = reverse %UNI2GSM; our $ESC = "\x1b"; our $ATMARK = "\x40"; our $FBCHAR = "\x3F"; our $NBSP = "\x{00A0}"; #define ERR_DECODE_NOMAP "%s \"\\x%02" UVXf "\" does not map to Unicode" sub decode ($$;$) { my ( $obj, $bytes, $chk ) = @_; return undef unless defined $bytes; my $str = substr($bytes, 0, 0); # to propagate taintedness; while ( length $bytes ) { my $c = substr( $bytes, 0, 1, '' ); my $u; if ( $c eq "\x00" ) { my $c2 = substr( $bytes, 0, 1, '' ); $u = !length $c2 ? $ATMARK : $c2 eq "\x00" ? "\x{0000}" : exists $GSM2UNI{$c2} ? $ATMARK . $GSM2UNI{$c2} : $chk ? croak sprintf( "\\x%02X\\x%02X does not map to Unicode", ord($c), ord($c2) ) : $ATMARK . $FBCHAR; } elsif ( $c eq $ESC ) { my $c2 = substr( $bytes, 0, 1, '' ); $u = exists $GSM2UNI{ $c . $c2 } ? $GSM2UNI{ $c . $c2 } : exists $GSM2UNI{$c2} ? $NBSP . $GSM2UNI{$c2} : $chk ? croak sprintf( "\\x%02X\\x%02X does not map to Unicode", ord($c), ord($c2) ) : $NBSP . $FBCHAR; } else { $u = exists $GSM2UNI{$c} ? $GSM2UNI{$c} : $chk ? ref $chk eq 'CODE' ? $chk->( ord $c ) : croak sprintf( "\\x%02X does not map to Unicode", ord($c) ) : $FBCHAR; } $str .= $u; } $_[1] = $bytes if $chk; return $str; } #define ERR_ENCODE_NOMAP "\"\\x{%04" UVxf "}\" does not map to %s" sub encode($$;$) { my ( $obj, $str, $chk ) = @_; return undef unless defined $str; my $bytes = substr($str, 0, 0); # to propagate taintedness while ( length $str ) { my $u = substr( $str, 0, 1, '' ); my $c; $bytes .= exists $UNI2GSM{$u} ? $UNI2GSM{$u} : $chk ? ref $chk eq 'CODE' ? $chk->( ord($u) ) : croak sprintf( "\\x{%04x} does not map to %s", ord($u), $obj->name ) : $FBCHAR; } $_[1] = $str if $chk; return $bytes; } 1; __END__ =head1 NAME Encode::GSM0338 -- ESTI GSM 03.38 Encoding =head1 SYNOPSIS use Encode qw/encode decode/; $gsm0338 = encode("gsm0338", $utf8); # loads Encode::GSM0338 implicitly $utf8 = decode("gsm0338", $gsm0338); # ditto =head1 DESCRIPTION GSM0338 is for GSM handsets. Though it shares alphanumerals with ASCII, control character ranges and other parts are mapped very differently, mainly to store Greek characters. There are also escape sequences (starting with 0x1B) to cover e.g. the Euro sign. This was once handled by L
but because of all those unusual specifications, Encode 2.20 has relocated the support to this module. =head1 NOTES Unlike most other encodings, the following always croaks on error for any $chk that evaluates to true. $gsm0338 = encode("gsm0338", $utf8 $chk); $utf8 = decode("gsm0338", $gsm0338, $chk); So if you want to check the validity of the encoding, surround the expression with C
block as follows; eval { $utf8 = decode("gsm0338", $gsm0338, $chk); } or do { # handle exception here }; =head1 BUGS ESTI GSM 03.38 Encoding itself. Mapping \x00 to '@' causes too much pain everywhere. Its use of \x1b (escape) is also very questionable. Because of those two, the code paging approach used use in ucm-based Encoding SOMETIMES fails so this module was written. =head1 SEE ALSO L
=cut PK #\Vzr~ ~ Byte.pmnu [ package Encode::Byte; use strict; use warnings; use Encode; our $VERSION = do { my @r = ( q$Revision: 2.4 $ =~ /\d+/g ); sprintf "%d." . "%02d" x $#r, @r }; use XSLoader; XSLoader::load( __PACKAGE__, $VERSION ); 1; __END__ =head1 NAME Encode::Byte - Single Byte Encodings =head1 SYNOPSIS use Encode qw/encode decode/; $greek = encode("iso-8859-7", $utf8); # loads Encode::Byte implicitly $utf8 = decode("iso-8859-7", $greek); # ditto =head1 ABSTRACT This module implements various single byte encodings. For most cases it uses \x80-\xff (upper half) to map non-ASCII characters. Encodings supported are as follows. Canonical Alias Description -------------------------------------------------------------------- # ISO 8859 series (iso-8859-1 is in built-in) iso-8859-2 latin2 [ISO] iso-8859-3 latin3 [ISO] iso-8859-4 latin4 [ISO] iso-8859-5 [ISO] iso-8859-6 [ISO] iso-8859-7 [ISO] iso-8859-8 [ISO] iso-8859-9 latin5 [ISO] iso-8859-10 latin6 [ISO] iso-8859-11 (iso-8859-12 is nonexistent) iso-8859-13 latin7 [ISO] iso-8859-14 latin8 [ISO] iso-8859-15 latin9 [ISO] iso-8859-16 latin10 [ISO] # Cyrillic koi8-f koi8-r cp878 [RFC1489] koi8-u [RFC2319] # Vietnamese viscii # all cp* are also available as ibm-*, ms-*, and windows-* # also see L
cp424 cp437 cp737 cp775 cp850 cp852 cp855 cp856 cp857 cp860 cp861 cp862 cp863 cp864 cp865 cp866 cp869 cp874 cp1006 cp1250 WinLatin2 cp1251 WinCyrillic cp1252 WinLatin1 cp1253 WinGreek cp1254 WinTurkish cp1255 WinHebrew cp1256 WinArabic cp1257 WinBaltic cp1258 WinVietnamese # Macintosh # Also see L
MacArabic MacCentralEurRoman MacCroatian MacCyrillic MacFarsi MacGreek MacHebrew MacIcelandic MacRoman MacRomanian MacRumanian MacSami MacThai MacTurkish MacUkrainian # More vendor encodings AdobeStandardEncoding nextstep hp-roman8 =head1 DESCRIPTION To find how to use this module in detail, see L
. =head1 SEE ALSO L
=cut PK #\f\ Changes.e2xnu [ # # $Id: Changes.e2x,v 2.0 2004/05/16 20:55:15 dankogai Exp $ # Revision history for Perl extension Encode::$_Name_. # 0.01 $_Now_ Autogenerated by enc2xs version $_Version_. PK #\{4 JP/H2Z.pmnu [ # # $Id: H2Z.pm,v 2.2 2006/06/03 20:28:48 dankogai Exp $ # package Encode::JP::H2Z; use strict; use warnings; our $RCSID = q$Id: H2Z.pm,v 2.2 2006/06/03 20:28:48 dankogai Exp $; our $VERSION = do { my @r = ( q$Revision: 2.2 $ =~ /\d+/g ); sprintf "%d." . "%02d" x $#r, @r }; use Encode::CJKConstants qw(:all); use vars qw(%_D2Z $_PAT_D2Z %_Z2D $_PAT_Z2D %_H2Z $_PAT_H2Z %_Z2H $_PAT_Z2H); %_H2Z = ( "\x8e\xa1" => "\xa1\xa3", # "\x8e\xa2" => "\xa1\xd6", # "\x8e\xa3" => "\xa1\xd7", # "\x8e\xa4" => "\xa1\xa2", # "\x8e\xa5" => "\xa1\xa6", # "\x8e\xa6" => "\xa5\xf2", # "\x8e\xa7" => "\xa5\xa1", # "\x8e\xa8" => "\xa5\xa3", # "\x8e\xa9" => "\xa5\xa5", # "\x8e\xaa" => "\xa5\xa7", # "\x8e\xab" => "\xa5\xa9", # "\x8e\xac" => "\xa5\xe3", # "\x8e\xad" => "\xa5\xe5", # "\x8e\xae" => "\xa5\xe7", # "\x8e\xaf" => "\xa5\xc3", # "\x8e\xb0" => "\xa1\xbc", # "\x8e\xb1" => "\xa5\xa2", # "\x8e\xb2" => "\xa5\xa4", # "\x8e\xb3" => "\xa5\xa6", # "\x8e\xb4" => "\xa5\xa8", # "\x8e\xb5" => "\xa5\xaa", # "\x8e\xb6" => "\xa5\xab", # "\x8e\xb7" => "\xa5\xad", # "\x8e\xb8" => "\xa5\xaf", # "\x8e\xb9" => "\xa5\xb1", # "\x8e\xba" => "\xa5\xb3", # "\x8e\xbb" => "\xa5\xb5", # "\x8e\xbc" => "\xa5\xb7", # "\x8e\xbd" => "\xa5\xb9", # "\x8e\xbe" => "\xa5\xbb", # "\x8e\xbf" => "\xa5\xbd", # "\x8e\xc0" => "\xa5\xbf", # "\x8e\xc1" => "\xa5\xc1", # "\x8e\xc2" => "\xa5\xc4", # "\x8e\xc3" => "\xa5\xc6", # "\x8e\xc4" => "\xa5\xc8", # "\x8e\xc5" => "\xa5\xca", # "\x8e\xc6" => "\xa5\xcb", # "\x8e\xc7" => "\xa5\xcc", # "\x8e\xc8" => "\xa5\xcd", # "\x8e\xc9" => "\xa5\xce", # "\x8e\xca" => "\xa5\xcf", # "\x8e\xcb" => "\xa5\xd2", # "\x8e\xcc" => "\xa5\xd5", # "\x8e\xcd" => "\xa5\xd8", # "\x8e\xce" => "\xa5\xdb", # "\x8e\xcf" => "\xa5\xde", # "\x8e\xd0" => "\xa5\xdf", # "\x8e\xd1" => "\xa5\xe0", # "\x8e\xd2" => "\xa5\xe1", # "\x8e\xd3" => "\xa5\xe2", # "\x8e\xd4" => "\xa5\xe4", # "\x8e\xd5" => "\xa5\xe6", # "\x8e\xd6" => "\xa5\xe8", # "\x8e\xd7" => "\xa5\xe9", # "\x8e\xd8" => "\xa5\xea", # "\x8e\xd9" => "\xa5\xeb", # "\x8e\xda" => "\xa5\xec", # "\x8e\xdb" => "\xa5\xed", # "\x8e\xdc" => "\xa5\xef", # "\x8e\xdd" => "\xa5\xf3", # "\x8e\xde" => "\xa1\xab", # "\x8e\xdf" => "\xa1\xac", # ); %_D2Z = ( "\x8e\xb6\x8e\xde" => "\xa5\xac", # "\x8e\xb7\x8e\xde" => "\xa5\xae", # "\x8e\xb8\x8e\xde" => "\xa5\xb0", # "\x8e\xb9\x8e\xde" => "\xa5\xb2", # "\x8e\xba\x8e\xde" => "\xa5\xb4", # "\x8e\xbb\x8e\xde" => "\xa5\xb6", # "\x8e\xbc\x8e\xde" => "\xa5\xb8", # "\x8e\xbd\x8e\xde" => "\xa5\xba", # "\x8e\xbe\x8e\xde" => "\xa5\xbc", # "\x8e\xbf\x8e\xde" => "\xa5\xbe", # "\x8e\xc0\x8e\xde" => "\xa5\xc0", # "\x8e\xc1\x8e\xde" => "\xa5\xc2", # "\x8e\xc2\x8e\xde" => "\xa5\xc5", # "\x8e\xc3\x8e\xde" => "\xa5\xc7", # "\x8e\xc4\x8e\xde" => "\xa5\xc9", # "\x8e\xca\x8e\xde" => "\xa5\xd0", # "\x8e\xcb\x8e\xde" => "\xa5\xd3", # "\x8e\xcc\x8e\xde" => "\xa5\xd6", # "\x8e\xcd\x8e\xde" => "\xa5\xd9", # "\x8e\xce\x8e\xde" => "\xa5\xdc", # "\x8e\xca\x8e\xdf" => "\xa5\xd1", # "\x8e\xcb\x8e\xdf" => "\xa5\xd4", # "\x8e\xcc\x8e\xdf" => "\xa5\xd7", # "\x8e\xcd\x8e\xdf" => "\xa5\xda", # "\x8e\xce\x8e\xdf" => "\xa5\xdd", # "\x8e\xb3\x8e\xde" => "\xa5\xf4", # ); # init only once; #$_PAT_D2Z = join("|", keys %_D2Z); #$_PAT_H2Z = join("|", keys %_H2Z); %_Z2H = reverse %_H2Z; %_Z2D = reverse %_D2Z; #$_PAT_Z2H = join("|", keys %_Z2H); #$_PAT_Z2D = join("|", keys %_Z2D); sub h2z { no warnings qw(uninitialized); my $r_str = shift; my ($keep_dakuten) = @_; my $n = 0; unless ($keep_dakuten) { $n = ( $$r_str =~ s( ($RE{EUC_KANA} (?:\x8e[\xde\xdf])?) ){ my $str = $1; $_D2Z{$str} || $_H2Z{$str} || # in case dakuten and handakuten are side-by-side! $_H2Z{substr($str,0,2)} . $_H2Z{substr($str,2,2)}; }eogx ); } else { $n = ( $$r_str =~ s( ($RE{EUC_KANA}) ){ $_H2Z{$1}; }eogx ); } $n; } sub z2h { my $r_str = shift; my $n = ( $$r_str =~ s( ($RE{EUC_C}|$RE{EUC_0212}|$RE{EUC_KANA}) ){ $_Z2D{$1} || $_Z2H{$1} || $1; }eogx ); $n; } 1; __END__ =head1 NAME Encode::JP::H2Z -- internally used by Encode::JP::2022_JP* =cut PK #\o JP/JIS7.pmnu [ package Encode::JP::JIS7; use strict; use warnings; our $VERSION = do { my @r = ( q$Revision: 2.8 $ =~ /\d+/g ); sprintf "%d." . "%02d" x $#r, @r }; use Encode qw(:fallbacks); for my $name ( '7bit-jis', 'iso-2022-jp', 'iso-2022-jp-1' ) { my $h2z = ( $name eq '7bit-jis' ) ? 0 : 1; my $jis0212 = ( $name eq 'iso-2022-jp' ) ? 0 : 1; my $obj = bless { Name => $name, h2z => $h2z, jis0212 => $jis0212, } => __PACKAGE__; Encode::define_encoding($obj, $name); } use parent qw(Encode::Encoding); # we override this to 1 so PerlIO works sub needs_lines { 1 } use Encode::CJKConstants qw(:all); # # decode is identical for all 2022 variants # sub decode($$;$) { my ( $obj, $str, $chk ) = @_; return undef unless defined $str; my $residue = ''; if ($chk) { $str =~ s/([^\x00-\x7f].*)$//so and $residue = $1; } $residue .= jis_euc( \$str ); $_[1] = $residue if $chk; return Encode::decode( 'euc-jp', $str, FB_PERLQQ ); } # # encode is different # sub encode($$;$) { require Encode::JP::H2Z; my ( $obj, $utf8, $chk ) = @_; return undef unless defined $utf8; # empty the input string in the stack so perlio is ok $_[1] = '' if $chk; my ( $h2z, $jis0212 ) = @$obj{qw(h2z jis0212)}; my $octet = Encode::encode( 'euc-jp', $utf8, $chk || 0 ); $h2z and &Encode::JP::H2Z::h2z( \$octet ); euc_jis( \$octet, $jis0212 ); return $octet; } # # cat_decode # my $re_scan_jis_g = qr{ \G ( ($RE{JIS_0212}) | $RE{JIS_0208} | ($RE{ISO_ASC}) | ($RE{JIS_KANA}) | ) ([^\e]*) }x; sub cat_decode { # ($obj, $dst, $src, $pos, $trm, $chk) my ( $obj, undef, undef, $pos, $trm ) = @_; # currently ignores $chk my ( $rdst, $rsrc, $rpos ) = \@_[ 1, 2, 3 ]; local ${^ENCODING}; use bytes; my $opos = pos($$rsrc); pos($$rsrc) = $pos; while ( $$rsrc =~ /$re_scan_jis_g/gc ) { my ( $esc, $esc_0212, $esc_asc, $esc_kana, $chunk ) = ( $1, $2, $3, $4, $5 ); unless ($chunk) { $esc or last; next; } if ( $esc && !$esc_asc ) { $chunk =~ tr/\x21-\x7e/\xa1-\xfe/; if ($esc_kana) { $chunk =~ s/([\xa1-\xdf])/\x8e$1/og; } elsif ($esc_0212) { $chunk =~ s/([\xa1-\xfe][\xa1-\xfe])/\x8f$1/og; } $chunk = Encode::decode( 'euc-jp', $chunk, 0 ); } elsif ( ( my $npos = index( $chunk, $trm ) ) >= 0 ) { $$rdst .= substr( $chunk, 0, $npos + length($trm) ); $$rpos += length($esc) + $npos + length($trm); pos($$rsrc) = $opos; return 1; } $$rdst .= $chunk; $$rpos = pos($$rsrc); } $$rpos = pos($$rsrc); pos($$rsrc) = $opos; return ''; } # JIS<->EUC my $re_scan_jis = qr{ (?:($RE{JIS_0212})|$RE{JIS_0208}|($RE{ISO_ASC})|($RE{JIS_KANA}))([^\e]*) }x; sub jis_euc { local ${^ENCODING}; my $r_str = shift; $$r_str =~ s($re_scan_jis) { my ($esc_0212, $esc_asc, $esc_kana, $chunk) = ($1, $2, $3, $4); if (!$esc_asc) { $chunk =~ tr/\x21-\x7e/\xa1-\xfe/; if ($esc_kana) { $chunk =~ s/([\xa1-\xdf])/\x8e$1/og; } elsif ($esc_0212) { $chunk =~ s/([\xa1-\xfe][\xa1-\xfe])/\x8f$1/og; } } $chunk; }geox; my ($residue) = ( $$r_str =~ s/(\e.*)$//so ); return $residue; } sub euc_jis { no warnings qw(uninitialized); local ${^ENCODING}; my $r_str = shift; my $jis0212 = shift; $$r_str =~ s{ ((?:$RE{EUC_C})+|(?:$RE{EUC_KANA})+|(?:$RE{EUC_0212})+) }{ my $chunk = $1; my $esc = ( $chunk =~ tr/\x8E//d ) ? $ESC{KANA} : ( $chunk =~ tr/\x8F//d ) ? $ESC{JIS_0212} : $ESC{JIS_0208}; if ($esc eq $ESC{JIS_0212} && !$jis0212){ # fallback to '?' $chunk =~ tr/\xA1-\xFE/\x3F/; }else{ $chunk =~ tr/\xA1-\xFE/\x21-\x7E/; } $esc . $chunk . $ESC{ASC}; }geox; $$r_str =~ s/\Q$ESC{ASC}\E (\Q$ESC{KANA}\E|\Q$ESC{JIS_0212}\E|\Q$ESC{JIS_0208}\E)/$1/gox; $$r_str; } 1; __END__ =head1 NAME Encode::JP::JIS7 -- internally used by Encode::JP =cut PK #\@O O Symbol.pmnu [ package Encode::Symbol; use strict; use warnings; use Encode; our $VERSION = do { my @r = ( q$Revision: 2.2 $ =~ /\d+/g ); sprintf "%d." . "%02d" x $#r, @r }; use XSLoader; XSLoader::load( __PACKAGE__, $VERSION ); 1; __END__ =head1 NAME Encode::Symbol - Symbol Encodings =head1 SYNOPSIS use Encode qw/encode decode/; $symbol = encode("symbol", $utf8); # loads Encode::Symbol implicitly $utf8 = decode("", $symbol); # ditto =head1 ABSTRACT This module implements symbol and dingbats encodings. Encodings supported are as follows. Canonical Alias Description -------------------------------------------------------------------- symbol dingbats AdobeZDingbat AdobeSymbol MacDingbats =head1 DESCRIPTION To find out how to use this module in detail, see L
. =head1 SEE ALSO L
=cut PK #\1H TW.pmnu [ package Encode::TW; BEGIN { if ( ord("A") == 193 ) { die "Encode::TW not supported on EBCDIC\n"; } } use strict; use warnings; use Encode; our $VERSION = do { my @r = ( q$Revision: 2.3 $ =~ /\d+/g ); sprintf "%d." . "%02d" x $#r, @r }; use XSLoader; XSLoader::load( __PACKAGE__, $VERSION ); 1; __END__ =head1 NAME Encode::TW - Taiwan-based Chinese Encodings =head1 SYNOPSIS use Encode qw/encode decode/; $big5 = encode("big5", $utf8); # loads Encode::TW implicitly $utf8 = decode("big5", $big5); # ditto =head1 DESCRIPTION This module implements tradition Chinese charset encodings as used in Taiwan and Hong Kong. Encodings supported are as follows. Canonical Alias Description -------------------------------------------------------------------- big5-eten /\bbig-?5$/i Big5 encoding (with ETen extensions) /\bbig5-?et(en)?$/i /\btca-?big5$/i big5-hkscs /\bbig5-?hk(scs)?$/i /\bhk(scs)?-?big5$/i Big5 + Cantonese characters in Hong Kong MacChineseTrad Big5 + Apple Vendor Mappings cp950 Code Page 950 = Big5 + Microsoft vendor mappings -------------------------------------------------------------------- To find out how to use this module in detail, see L
. =head1 NOTES Due to size concerns, C
(Extended Unix Character), C
(Chinese Character Code for Information Interchange), C
(CMEX's Big5+) and C
(CMEX's Big5e) are distributed separately on CPAN, under the name L
. That module also contains extra China-based encodings. =head1 BUGS Since the original C
encoding (1984) is not supported anywhere (glibc and DOS-based systems uses C
to mean C
; Microsoft uses C
to mean C
), a conscious decision was made to alias C
to C
, which is the de facto superset of the original big5. The C
encoding files are not complete. For common C
manipulation, please use C
in L
, which contains planes 1-7. The ASCII region (0x00-0x7f) is preserved for all encodings, even though this conflicts with mappings by the Unicode Consortium. =head1 SEE ALSO L
=cut PK #\"0k^# # Unicode/UTF7.pmnu [ # # $Id: UTF7.pm,v 2.10 2017/06/10 17:23:50 dankogai Exp $ # package Encode::Unicode::UTF7; use strict; use warnings; use parent qw(Encode::Encoding); __PACKAGE__->Define('UTF-7'); our $VERSION = do { my @r = ( q$Revision: 2.10 $ =~ /\d+/g ); sprintf "%d." . "%02d" x $#r, @r }; use MIME::Base64; use Encode qw(find_encoding); # # Algorithms taken from Unicode::String by Gisle Aas # our $OPTIONAL_DIRECT_CHARS = 1; my $specials = quotemeta "\'(),-./:?"; $OPTIONAL_DIRECT_CHARS and $specials .= quotemeta "!\"#$%&*;<=>@[]^_`{|}"; # \s will not work because it matches U+3000 DEOGRAPHIC SPACE # We use qr/[\n\r\t\ ] instead my $re_asis = qr/(?:[\n\r\t\ A-Za-z0-9$specials])/; my $re_encoded = qr/(?:[^\n\r\t\ A-Za-z0-9$specials])/; my $e_utf16 = find_encoding("UTF-16BE"); sub needs_lines { 1 } sub encode($$;$) { my ( $obj, $str, $chk ) = @_; return undef unless defined $str; my $len = length($str); pos($str) = 0; my $bytes = substr($str, 0, 0); # to propagate taintedness while ( pos($str) < $len ) { if ( $str =~ /\G($re_asis+)/ogc ) { my $octets = $1; utf8::downgrade($octets); $bytes .= $octets; } elsif ( $str =~ /\G($re_encoded+)/ogsc ) { if ( $1 eq "+" ) { $bytes .= "+-"; } else { my $s = $1; my $base64 = encode_base64( $e_utf16->encode($s), '' ); $base64 =~ s/=+$//; $bytes .= "+$base64-"; } } else { die "This should not happen! (pos=" . pos($str) . ")"; } } $_[1] = '' if $chk; return $bytes; } sub decode($$;$) { use re 'taint'; my ( $obj, $bytes, $chk ) = @_; return undef unless defined $bytes; my $len = length($bytes); my $str = substr($bytes, 0, 0); # to propagate taintedness; pos($bytes) = 0; no warnings 'uninitialized'; while ( pos($bytes) < $len ) { if ( $bytes =~ /\G([^+]+)/ogc ) { $str .= $1; } elsif ( $bytes =~ /\G\+-/ogc ) { $str .= "+"; } elsif ( $bytes =~ /\G\+([A-Za-z0-9+\/]+)-?/ogsc ) { my $base64 = $1; my $pad = length($base64) % 4; $base64 .= "=" x ( 4 - $pad ) if $pad; $str .= $e_utf16->decode( decode_base64($base64) ); } elsif ( $bytes =~ /\G\+/ogc ) { $^W and warn "Bad UTF7 data escape"; $str .= "+"; } else { die "This should not happen " . pos($bytes); } } $_[1] = '' if $chk; return $str; } 1; __END__ =head1 NAME Encode::Unicode::UTF7 -- UTF-7 encoding =head1 SYNOPSIS use Encode qw/encode decode/; $utf7 = encode("UTF-7", $utf8); $utf8 = decode("UTF-7", $ucs2); =head1 ABSTRACT This module implements UTF-7 encoding documented in RFC 2152. UTF-7, as its name suggests, is a 7-bit re-encoded version of UTF-16BE. It is designed to be MTA-safe and expected to be a standard way to exchange Unicoded mails via mails. But with the advent of UTF-8 and 8-bit compliant MTAs, UTF-7 is hardly ever used. UTF-7 was not supported by Encode until version 1.95 because of that. But Unicode::String, a module by Gisle Aas which adds Unicode supports to non-utf8-savvy perl did support UTF-7, the UTF-7 support was added so Encode can supersede Unicode::String 100%. =head1 In Practice When you want to encode Unicode for mails and web pages, however, do not use UTF-7 unless you are sure your recipients and readers can handle it. Very few MUAs and WWW Browsers support these days (only Mozilla seems to support one). For general cases, use UTF-8 for message body and MIME-Header for header instead. =head1 SEE ALSO L
, L
, L
RFC 2781 L
=cut PK #\B 6z z JP.pmnu [ package Encode::JP; BEGIN { if ( ord("A") == 193 ) { die "Encode::JP not supported on EBCDIC\n"; } } use strict; use warnings; use Encode; our $VERSION = do { my @r = ( q$Revision: 2.4 $ =~ /\d+/g ); sprintf "%d." . "%02d" x $#r, @r }; use XSLoader; XSLoader::load( __PACKAGE__, $VERSION ); use Encode::JP::JIS7; 1; __END__ =head1 NAME Encode::JP - Japanese Encodings =head1 SYNOPSIS use Encode qw/encode decode/; $euc_jp = encode("euc-jp", $utf8); # loads Encode::JP implicitly $utf8 = decode("euc-jp", $euc_jp); # ditto =head1 ABSTRACT This module implements Japanese charset encodings. Encodings supported are as follows. Canonical Alias Description -------------------------------------------------------------------- euc-jp /\beuc.*jp$/i EUC (Extended Unix Character) /\bjp.*euc/i /\bujis$/i shiftjis /\bshift.*jis$/i Shift JIS (aka MS Kanji) /\bsjis$/i 7bit-jis /\bjis$/i 7bit JIS iso-2022-jp ISO-2022-JP [RFC1468] = 7bit JIS with all Halfwidth Kana converted to Fullwidth iso-2022-jp-1 ISO-2022-JP-1 [RFC2237] = ISO-2022-JP with JIS X 0212-1990 support. See below MacJapanese Shift JIS + Apple vendor mappings cp932 /\bwindows-31j$/i Code Page 932 = Shift JIS + MS/IBM vendor mappings jis0201-raw JIS0201, raw format jis0208-raw JIS0201, raw format jis0212-raw JIS0201, raw format -------------------------------------------------------------------- =head1 DESCRIPTION To find out how to use this module in detail, see L
. =head1 Note on ISO-2022-JP(-1)? ISO-2022-JP-1 (RFC2237) is a superset of ISO-2022-JP (RFC1468) which adds support for JIS X 0212-1990. That means you can use the same code to decode to utf8 but not vice versa. $utf8 = decode('iso-2022-jp-1', $stream); and $utf8 = decode('iso-2022-jp', $stream); yield the same result but $with_0212 = encode('iso-2022-jp-1', $utf8); is now different from $without_0212 = encode('iso-2022-jp', $utf8 ); In the latter case, characters that map to 0212 are first converted to U+3013 (0xA2AE in EUC-JP; a white square also known as 'Tofu' or 'geta mark') then fed to the decoding engine. U+FFFD is not used, in order to preserve text layout as much as possible. =head1 BUGS The ASCII region (0x00-0x7f) is preserved for all encodings, even though this conflicts with mappings by the Unicode Consortium. =head1 SEE ALSO L
=cut PK #\)A A MIME/Header.pmnu [ package Encode::MIME::Header; use strict; use warnings; our $VERSION = do { my @r = ( q$Revision: 2.28 $ =~ /\d+/g ); sprintf "%d." . "%02d" x $#r, @r }; use Carp (); use Encode (); use MIME::Base64 (); my %seed = ( decode_b => 1, # decodes 'B' encoding ? decode_q => 1, # decodes 'Q' encoding ? encode => 'B', # encode with 'B' or 'Q' ? charset => 'UTF-8', # encode charset bpl => 75, # bytes per line ); my @objs; push @objs, bless { %seed, Name => 'MIME-Header', } => __PACKAGE__; push @objs, bless { %seed, decode_q => 0, Name => 'MIME-B', } => __PACKAGE__; push @objs, bless { %seed, decode_b => 0, encode => 'Q', Name => 'MIME-Q', } => __PACKAGE__; Encode::define_encoding($_, $_->{Name}) foreach @objs; use parent qw(Encode::Encoding); sub needs_lines { 1 } sub perlio_ok { 0 } # RFC 2047 and RFC 2231 grammar my $re_charset = qr/[!"#\$%&'+\-0-9A-Z\\\^_`a-z\{\|\}~]+/; my $re_language = qr/[A-Za-z]{1,8}(?:-[0-9A-Za-z]{1,8})*/; my $re_encoding = qr/[QqBb]/; my $re_encoded_text = qr/[^\?]*/; my $re_encoded_word = qr/=\?$re_charset(?:\*$re_language)?\?$re_encoding\?$re_encoded_text\?=/; my $re_capture_encoded_word = qr/=\?($re_charset)((?:\*$re_language)?)\?($re_encoding\?$re_encoded_text)\?=/; my $re_capture_encoded_word_split = qr/=\?($re_charset)((?:\*$re_language)?)\?($re_encoding)\?($re_encoded_text)\?=/; # in strict mode check also for valid base64 characters and also for valid quoted printable codes my $re_encoding_strict_b = qr/[Bb]/; my $re_encoding_strict_q = qr/[Qq]/; my $re_encoded_text_strict_b = qr/[0-9A-Za-z\+\/]*={0,2}/; my $re_encoded_text_strict_q = qr/(?:[\x21-\x3C\x3E\x40-\x7E]|=[0-9A-Fa-f]{2})*/; # NOTE: first part are printable US-ASCII except ?, =, SPACE and TAB my $re_encoded_word_strict = qr/=\?$re_charset(?:\*$re_language)?\?(?:$re_encoding_strict_b\?$re_encoded_text_strict_b|$re_encoding_strict_q\?$re_encoded_text_strict_q)\?=/; my $re_capture_encoded_word_strict = qr/=\?($re_charset)((?:\*$re_language)?)\?($re_encoding_strict_b\?$re_encoded_text_strict_b|$re_encoding_strict_q\?$re_encoded_text_strict_q)\?=/; my $re_newline = qr/(?:\r\n|[\r\n])/; # in strict mode encoded words must be always separated by spaces or tabs (or folded newline) # except in comments when separator between words and comment round brackets can be omitted my $re_word_begin_strict = qr/(?:(?:[ \t]|\A)\(?|(?:[^\\]|\A)\)\()/; my $re_word_sep_strict = qr/(?:$re_newline?[ \t])+/; my $re_word_end_strict = qr/(?:\)\(|\)?(?:$re_newline?[ \t]|\z))/; my $re_match = qr/()((?:$re_encoded_word\s*)*$re_encoded_word)()/; my $re_match_strict = qr/($re_word_begin_strict)((?:$re_encoded_word_strict$re_word_sep_strict)*$re_encoded_word_strict)(?=$re_word_end_strict)/; my $re_capture = qr/$re_capture_encoded_word(?:\s*)?/; my $re_capture_strict = qr/$re_capture_encoded_word_strict$re_word_sep_strict?/; our $STRICT_DECODE = 0; sub decode($$;$) { my ($obj, $str, $chk) = @_; return undef unless defined $str; my $re_match_decode = $STRICT_DECODE ? $re_match_strict : $re_match; my $re_capture_decode = $STRICT_DECODE ? $re_capture_strict : $re_capture; my $stop = 0; my $output = substr($str, 0, 0); # to propagate taintedness # decode each line separately, match whole continuous folded line at one call 1 while not $stop and $str =~ s{^((?:[^\r\n]*(?:$re_newline[ \t])?)*)($re_newline)?}{ my $line = $1; my $sep = defined $2 ? $2 : ''; $stop = 1 unless length($line) or length($sep); # NOTE: this code partially could break $chk support # in non strict mode concat consecutive encoded mime words with same charset, language and encoding # fixes breaking inside multi-byte characters 1 while not $STRICT_DECODE and $line =~ s/$re_capture_encoded_word_split\s*=\?\1\2\?\3\?($re_encoded_text)\?=/=\?$1$2\?$3\?$4$5\?=/so; # process sequence of encoded MIME words at once 1 while not $stop and $line =~ s{^(.*?)$re_match_decode}{ my $begin = $1 . $2; my $words = $3; $begin =~ tr/\r\n//d; $output .= $begin; # decode one MIME word 1 while not $stop and $words =~ s{^(.*?)($re_capture_decode)}{ $output .= $1; my $orig = $2; my $charset = $3; my ($mime_enc, $text) = split /\?/, $5; $text =~ tr/\r\n//d; my $enc = Encode::find_mime_encoding($charset); # in non strict mode allow also perl encoding aliases if ( not defined $enc and not $STRICT_DECODE ) { # make sure that decoded string will be always strict UTF-8 $charset = 'UTF-8' if lc($charset) eq 'utf8'; $enc = Encode::find_encoding($charset); } if ( not defined $enc ) { Carp::croak qq(Unknown charset "$charset") if not ref $chk and $chk and $chk & Encode::DIE_ON_ERR; Carp::carp qq(Unknown charset "$charset") if not ref $chk and $chk and $chk & Encode::WARN_ON_ERR; $stop = 1 if not ref $chk and $chk and $chk & Encode::RETURN_ON_ERR; $output .= ($output =~ /(?:\A|[ \t])$/ ? '' : ' ') . $orig unless $stop; # $orig mime word is separated by whitespace $stop ? $orig : ''; } else { if ( uc($mime_enc) eq 'B' and $obj->{decode_b} ) { my $decoded = _decode_b($enc, $text, $chk); $stop = 1 if not defined $decoded and not ref $chk and $chk and $chk & Encode::RETURN_ON_ERR; $output .= (defined $decoded ? $decoded : $text) unless $stop; $stop ? $orig : ''; } elsif ( uc($mime_enc) eq 'Q' and $obj->{decode_q} ) { my $decoded = _decode_q($enc, $text, $chk); $stop = 1 if not defined $decoded and not ref $chk and $chk and $chk & Encode::RETURN_ON_ERR; $output .= (defined $decoded ? $decoded : $text) unless $stop; $stop ? $orig : ''; } else { Carp::croak qq(MIME "$mime_enc" unsupported) if not ref $chk and $chk and $chk & Encode::DIE_ON_ERR; Carp::carp qq(MIME "$mime_enc" unsupported) if not ref $chk and $chk and $chk & Encode::WARN_ON_ERR; $stop = 1 if not ref $chk and $chk and $chk & Encode::RETURN_ON_ERR; $output .= ($output =~ /(?:\A|[ \t])$/ ? '' : ' ') . $orig unless $stop; # $orig mime word is separated by whitespace $stop ? $orig : ''; } } }se; if ( not $stop ) { $output .= $words; $words = ''; } $words; }se; if ( not $stop ) { $line =~ tr/\r\n//d; $output .= $line . $sep; $line = ''; $sep = ''; } $line . $sep; }se; $_[1] = $str if not ref $chk and $chk and !($chk & Encode::LEAVE_SRC); return $output; } sub _decode_b { my ($enc, $text, $chk) = @_; # MIME::Base64::decode ignores everything after a '=' padding character # in non strict mode split string after each sequence of padding characters and decode each substring my $octets = $STRICT_DECODE ? MIME::Base64::decode($text) : join('', map { MIME::Base64::decode($_) } split /(?<==)(?=[^=])/, $text); return _decode_octets($enc, $octets, $chk); } sub _decode_q { my ($enc, $text, $chk) = @_; $text =~ s/_/ /go; $text =~ s/=([0-9A-Fa-f]{2})/pack('C', hex($1))/ego; return _decode_octets($enc, $text, $chk); } sub _decode_octets { my ($enc, $octets, $chk) = @_; $chk = 0 unless defined $chk; $chk &= ~Encode::LEAVE_SRC if not ref $chk and $chk; my $output = $enc->decode($octets, $chk); return undef if not ref $chk and $chk and $octets ne ''; return $output; } sub encode($$;$) { my ($obj, $str, $chk) = @_; return undef unless defined $str; my $output = $obj->_fold_line($obj->_encode_string($str, $chk)); $_[1] = $str if not ref $chk and $chk and !($chk & Encode::LEAVE_SRC); return $output . substr($str, 0, 0); # to propagate taintedness } sub _fold_line { my ($obj, $line) = @_; my $bpl = $obj->{bpl}; my $output = ''; while ( length($line) ) { if ( $line =~ s/^(.{0,$bpl})(\s|\z)// ) { $output .= $1; $output .= "\r\n" . $2 if length($line); } elsif ( $line =~ s/(\s)(.*)$// ) { $output .= $line; $line = $2; $output .= "\r\n" . $1 if length($line); } else { $output .= $line; last; } } return $output; } sub _encode_string { my ($obj, $str, $chk) = @_; my $wordlen = $obj->{bpl} > 76 ? 76 : $obj->{bpl}; my $enc = Encode::find_mime_encoding($obj->{charset}); my $enc_chk = $chk; $enc_chk = 0 unless defined $enc_chk; $enc_chk |= Encode::LEAVE_SRC if not ref $enc_chk and $enc_chk; my @result = (); my $octets = ''; while ( length( my $chr = substr($str, 0, 1, '') ) ) { my $seq = $enc->encode($chr, $enc_chk); if ( not length($seq) ) { substr($str, 0, 0, $chr); last; } if ( $obj->_encoded_word_len($octets . $seq) > $wordlen ) { push @result, $obj->_encode_word($octets); $octets = ''; } $octets .= $seq; } length($octets) and push @result, $obj->_encode_word($octets); $_[1] = $str if not ref $chk and $chk and !($chk & Encode::LEAVE_SRC); return join(' ', @result); } sub _encode_word { my ($obj, $octets) = @_; my $charset = $obj->{charset}; my $encode = $obj->{encode}; my $text = $encode eq 'B' ? _encode_b($octets) : _encode_q($octets); return "=?$charset?$encode?$text?="; } sub _encoded_word_len { my ($obj, $octets) = @_; my $charset = $obj->{charset}; my $encode = $obj->{encode}; my $text_len = $encode eq 'B' ? _encoded_b_len($octets) : _encoded_q_len($octets); return length("=?$charset?$encode??=") + $text_len; } sub _encode_b { my ($octets) = @_; return MIME::Base64::encode($octets, ''); } sub _encoded_b_len { my ($octets) = @_; return ( length($octets) + 2 ) / 3 * 4; } my $re_invalid_q_char = qr/[^0-9A-Za-z !*+\-\/]/; sub _encode_q { my ($octets) = @_; $octets =~ s{($re_invalid_q_char)}{ join('', map { sprintf('=%02X', $_) } unpack('C*', $1)) }egox; $octets =~ s/ /_/go; return $octets; } sub _encoded_q_len { my ($octets) = @_; my $invalid_count = () = $octets =~ /$re_invalid_q_char/sgo; return ( $invalid_count * 3 ) + ( length($octets) - $invalid_count ); } 1; __END__ =head1 NAME Encode::MIME::Header -- MIME encoding for an unstructured email header =head1 SYNOPSIS use Encode qw(encode decode); my $mime_str = encode("MIME-Header", "Sample:Text \N{U+263A}"); # $mime_str is "=?UTF-8?B?U2FtcGxlOlRleHQg4pi6?=" my $mime_q_str = encode("MIME-Q", "Sample:Text \N{U+263A}"); # $mime_q_str is "=?UTF-8?Q?Sample=3AText_=E2=98=BA?=" my $str = decode("MIME-Header", "=?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=\r\n " . "=?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=" ); # $str is "If you can read this you understand the example." use Encode qw(decode :fallbacks); use Encode::MIME::Header; local $Encode::MIME::Header::STRICT_DECODE = 1; my $strict_string = decode("MIME-Header", $mime_string, FB_CROAK); # use strict decoding and croak on errors =head1 ABSTRACT This module implements L
MIME encoding for an unstructured field body of the email header. It can also be used for L
'text' token. However, it cannot be used directly for the whole header with the field name or for the structured header fields like From, To, Cc, Message-Id, etc... There are 3 encoding names supported by this module: C
, C
and C
. =head1 DESCRIPTION Decode method takes an unstructured field body of the email header (or L
'text' token) as its input and decodes each MIME encoded-word from input string to a sequence of bytes according to L
and L
. Subsequently, each sequence of bytes with the corresponding MIME charset is decoded with L
and finally, one output string is returned. Text parts of the input string which do not contain MIME encoded-word stay unmodified in the output string. Folded newlines between two consecutive MIME encoded-words are discarded, others are preserved in the output string. C
can decode Base64 variant, C
can decode Quoted-Printable variant and C
can decode both of them. If L
does not support particular MIME charset or chosen variant then an action based on L
is performed (by default, the MIME encoded-word is not decoded). Encode method takes a scalar string as its input and uses L
encoder for encoding it to UTF-8 bytes. Then a sequence of UTF-8 bytes is encoded into MIME encoded-words (C
and C
use a Base64 variant while C
uses a Quoted-Printable variant) where each MIME encoded-word is limited to 75 characters. MIME encoded-words are separated by C
and joined to one output string. Output string is suitable for unstructured field body of the email header. Both encode and decode methods propagate L
when encoding and decoding the MIME charset. =head1 BUGS Versions prior to 2.22 (part of Encode 2.83) have a malfunctioning decoder and encoder. The MIME encoder infamously inserted additional spaces or discarded white spaces between consecutive MIME encoded-words, which led to invalid MIME headers produced by this module. The MIME decoder had a tendency to discard white spaces, incorrectly interpret data or attempt to decode Base64 MIME encoded-words as Quoted-Printable. These problems were fixed in version 2.22. It is highly recommended not to use any version prior 2.22! Versions prior to 2.24 (part of Encode 2.87) ignored L
. The MIME encoder used L
encoder for input Unicode strings which could lead to invalid UTF-8 sequences. MIME decoder used also L
decoder and additionally called the decode method with a C
flag (thus user-specified L
were ignored). Moreover, it automatically croaked when a MIME encoded-word contained unknown encoding. Since version 2.24, this module uses L
encoder and decoder. And L
are correctly propagated. Since version 2.22 (part of Encode 2.83), the MIME encoder should be fully compliant to L
and L
. Due to the aforementioned bugs in previous versions of the MIME encoder, there is a I
compatible mode for the MIME decoder which is used by default. It should be able to decode MIME encoded-words encoded by pre 2.22 versions of this module. However, note that this is not correct according to L
. In default I
mode the MIME decoder attempts to decode every substring which looks like a MIME encoded-word. Therefore, the MIME encoded-words do not need to be separated by white space. To enforce a correct I
mode, set variable C<$Encode::MIME::Header::STRICT_DECODE> to 1 e.g. by localizing: use Encode::MIME::Header; local $Encode::MIME::Header::STRICT_DECODE = 1; =head1 AUTHORS Pali E
pali@cpan.orgE
=head1 SEE ALSO L
, L
, L
, L
=cut PK #\J)ߝ MIME/Header/ISO_2022_JP.pmnu [ package Encode::MIME::Header::ISO_2022_JP; use strict; use warnings; use parent qw(Encode::MIME::Header); my $obj = bless { decode_b => '1', decode_q => '1', encode => 'B', bpl => 76, Name => 'MIME-Header-ISO_2022_JP' } => __PACKAGE__; Encode::define_encoding($obj, 'MIME-Header-ISO_2022_JP'); use constant HEAD => '=?ISO-2022-JP?B?'; use constant TAIL => '?='; use Encode::CJKConstants qw(%RE); our $VERSION = do { my @r = ( q$Revision: 1.9 $ =~ /\d+/g ); sprintf "%d." . "%02d" x $#r, @r }; # I owe the below codes totally to # Jcode by Dan Kogai & http://www.din.or.jp/~ohzaki/perl.htm#JP_Base64 sub encode { my $self = shift; my $str = shift; return undef unless defined $str; utf8::encode($str) if ( Encode::is_utf8($str) ); Encode::from_to( $str, 'utf8', 'euc-jp' ); my ($trailing_crlf) = ( $str =~ /(\n|\r|\x0d\x0a)$/o ); $str = _mime_unstructured_header( $str, $self->{bpl} ); not $trailing_crlf and $str =~ s/(\n|\r|\x0d\x0a)$//o; return $str; } sub _mime_unstructured_header { my ( $oldheader, $bpl ) = @_; my $crlf = $oldheader =~ /\n$/; my ( $header, @words, @wordstmp, $i ) = (''); $oldheader =~ s/\s+$//; @wordstmp = split /\s+/, $oldheader; for ( $i = 0 ; $i < $#wordstmp ; $i++ ) { if ( $wordstmp[$i] !~ /^[\x21-\x7E]+$/ and $wordstmp[ $i + 1 ] !~ /^[\x21-\x7E]+$/ ) { $wordstmp[ $i + 1 ] = "$wordstmp[$i] $wordstmp[$i + 1]"; } else { push( @words, $wordstmp[$i] ); } } push( @words, $wordstmp[-1] ); for my $word (@words) { if ( $word =~ /^[\x21-\x7E]+$/ ) { $header =~ /(?:.*\n)*(.*)/; if ( length($1) + length($word) > $bpl ) { $header .= "\n $word"; } else { $header .= $word; } } else { $header = _add_encoded_word( $word, $header, $bpl ); } $header =~ /(?:.*\n)*(.*)/; if ( length($1) == $bpl ) { $header .= "\n "; } else { $header .= ' '; } } $header =~ s/\n? $//mg; $crlf ? "$header\n" : $header; } sub _add_encoded_word { my ( $str, $line, $bpl ) = @_; my $result = ''; while ( length($str) ) { my $target = $str; $str = ''; if ( length($line) + 22 + ( $target =~ /^(?:$RE{EUC_0212}|$RE{EUC_C})/o ) * 8 > $bpl ) { $line =~ s/[ \t\n\r]*$/\n/; $result .= $line; $line = ' '; } while (1) { my $iso_2022_jp = $target; Encode::from_to( $iso_2022_jp, 'euc-jp', 'iso-2022-jp' ); my $encoded = HEAD . MIME::Base64::encode_base64( $iso_2022_jp, '' ) . TAIL; if ( length($encoded) + length($line) > $bpl ) { $target =~ s/($RE{EUC_0212}|$RE{EUC_KANA}|$RE{EUC_C}|$RE{ASCII})$//o; $str = $1 . $str; } else { $line .= $encoded; last; } } } $result . $line; } 1; __END__ PK #\] MIME/Name.pmnu [ package Encode::MIME::Name; use strict; use warnings; our $VERSION = do { my @r = ( q$Revision: 1.3 $ =~ /\d+/g ); sprintf "%d." . "%02d" x $#r, @r }; # NOTE: This table must be 1:1 mapping our %MIME_NAME_OF = ( 'AdobeStandardEncoding' => 'Adobe-Standard-Encoding', 'AdobeSymbol' => 'Adobe-Symbol-Encoding', 'ascii' => 'US-ASCII', 'big5-hkscs' => 'Big5-HKSCS', 'cp1026' => 'IBM1026', 'cp1047' => 'IBM1047', 'cp1250' => 'windows-1250', 'cp1251' => 'windows-1251', 'cp1252' => 'windows-1252', 'cp1253' => 'windows-1253', 'cp1254' => 'windows-1254', 'cp1255' => 'windows-1255', 'cp1256' => 'windows-1256', 'cp1257' => 'windows-1257', 'cp1258' => 'windows-1258', 'cp37' => 'IBM037', 'cp424' => 'IBM424', 'cp437' => 'IBM437', 'cp500' => 'IBM500', 'cp775' => 'IBM775', 'cp850' => 'IBM850', 'cp852' => 'IBM852', 'cp855' => 'IBM855', 'cp857' => 'IBM857', 'cp860' => 'IBM860', 'cp861' => 'IBM861', 'cp862' => 'IBM862', 'cp863' => 'IBM863', 'cp864' => 'IBM864', 'cp865' => 'IBM865', 'cp866' => 'IBM866', 'cp869' => 'IBM869', 'cp936' => 'GBK', 'euc-cn' => 'EUC-CN', 'euc-jp' => 'EUC-JP', 'euc-kr' => 'EUC-KR', #'gb2312-raw' => 'GB2312', # no, you're wrong, I18N::Charset 'hp-roman8' => 'hp-roman8', 'hz' => 'HZ-GB-2312', 'iso-2022-jp' => 'ISO-2022-JP', 'iso-2022-jp-1' => 'ISO-2022-JP-1', 'iso-2022-kr' => 'ISO-2022-KR', 'iso-8859-1' => 'ISO-8859-1', 'iso-8859-10' => 'ISO-8859-10', 'iso-8859-13' => 'ISO-8859-13', 'iso-8859-14' => 'ISO-8859-14', 'iso-8859-15' => 'ISO-8859-15', 'iso-8859-16' => 'ISO-8859-16', 'iso-8859-2' => 'ISO-8859-2', 'iso-8859-3' => 'ISO-8859-3', 'iso-8859-4' => 'ISO-8859-4', 'iso-8859-5' => 'ISO-8859-5', 'iso-8859-6' => 'ISO-8859-6', 'iso-8859-7' => 'ISO-8859-7', 'iso-8859-8' => 'ISO-8859-8', 'iso-8859-9' => 'ISO-8859-9', #'jis0201-raw' => 'JIS_X0201', #'jis0208-raw' => 'JIS_C6226-1983', #'jis0212-raw' => 'JIS_X0212-1990', 'koi8-r' => 'KOI8-R', 'koi8-u' => 'KOI8-U', #'ksc5601-raw' => 'KS_C_5601-1987', 'shiftjis' => 'Shift_JIS', 'UTF-16' => 'UTF-16', 'UTF-16BE' => 'UTF-16BE', 'UTF-16LE' => 'UTF-16LE', 'UTF-32' => 'UTF-32', 'UTF-32BE' => 'UTF-32BE', 'UTF-32LE' => 'UTF-32LE', 'UTF-7' => 'UTF-7', 'utf-8-strict' => 'UTF-8', 'viscii' => 'VISCII', ); # NOTE: %MIME_NAME_OF is still 1:1 mapping our %ENCODE_NAME_OF = map { uc $MIME_NAME_OF{$_} => $_ } keys %MIME_NAME_OF; # Add additional 1:N mapping $MIME_NAME_OF{'utf8'} = 'UTF-8'; sub get_mime_name($) { $MIME_NAME_OF{$_[0]} }; sub get_encode_name($) { $ENCODE_NAME_OF{uc $_[0]} }; 1; __END__ =head1 NAME Encode::MIME::NAME -- internally used by Encode =head1 SEE ALSO L
=cut PK #\ԃ@ ConfigLocal_PM.e2xnu [ # # Local demand-load module list # # You should not edit this file by hand! use "enc2xs -C" # package Encode::ConfigLocal; our $VERSION = $_LocalVer_; use strict; $_ModLines_ 1; PK #\hHa a EBCDIC.pmnu [ package Encode::EBCDIC; use strict; use warnings; use Encode; our $VERSION = do { my @r = ( q$Revision: 2.2 $ =~ /\d+/g ); sprintf "%d." . "%02d" x $#r, @r }; use XSLoader; XSLoader::load( __PACKAGE__, $VERSION ); 1; __END__ =head1 NAME Encode::EBCDIC - EBCDIC Encodings =head1 SYNOPSIS use Encode qw/encode decode/; $posix_bc = encode("posix-bc", $utf8); # loads Encode::EBCDIC implicitly $utf8 = decode("", $posix_bc); # ditto =head1 ABSTRACT This module implements various EBCDIC-Based encodings. Encodings supported are as follows. Canonical Alias Description -------------------------------------------------------------------- cp37 cp500 cp875 cp1026 cp1047 posix-bc =head1 DESCRIPTION To find how to use this module in detail, see L
. =head1 SEE ALSO L
, L
=cut PK #\ >" " Unicode.pmnu [ package Encode::Unicode; use strict; use warnings; our $VERSION = do { my @r = ( q$Revision: 2.17 $ =~ /\d+/g ); sprintf "%d." . "%02d" x $#r, @r }; use XSLoader; XSLoader::load( __PACKAGE__, $VERSION ); # # Object Generator 8 transcoders all at once! # use Encode (); our %BOM_Unknown = map { $_ => 1 } qw(UTF-16 UTF-32); for my $name ( qw(UTF-16 UTF-16BE UTF-16LE UTF-32 UTF-32BE UTF-32LE UCS-2BE UCS-2LE) ) { my ( $size, $endian, $ucs2, $mask ); $name =~ /^(\w+)-(\d+)(\w*)$/o; if ( $ucs2 = ( $1 eq 'UCS' ) ) { $size = 2; } else { $size = $2 / 8; } $endian = ( $3 eq 'BE' ) ? 'n' : ( $3 eq 'LE' ) ? 'v' : ''; $size == 4 and $endian = uc($endian); my $obj = bless { Name => $name, size => $size, endian => $endian, ucs2 => $ucs2, } => __PACKAGE__; Encode::define_encoding($obj, $name); } use parent qw(Encode::Encoding); sub renew { my $self = shift; $BOM_Unknown{ $self->name } or return $self; my $clone = bless {%$self} => ref($self); $clone->{renewed}++; # so the caller knows it is renewed. return $clone; } 1; __END__ =head1 NAME Encode::Unicode -- Various Unicode Transformation Formats =cut =head1 SYNOPSIS use Encode qw/encode decode/; $ucs2 = encode("UCS-2BE", $utf8); $utf8 = decode("UCS-2BE", $ucs2); =head1 ABSTRACT This module implements all Character Encoding Schemes of Unicode that are officially documented by Unicode Consortium (except, of course, for UTF-8, which is a native format in perl). =over 4 =item L
says: I
A character encoding form plus byte serialization. There are Seven character encoding schemes in Unicode: UTF-8, UTF-16, UTF-16BE, UTF-16LE, UTF-32 (UCS-4), UTF-32BE (UCS-4BE) and UTF-32LE (UCS-4LE), and UTF-7. Since UTF-7 is a 7-bit (re)encoded version of UTF-16BE, It is not part of Unicode's Character Encoding Scheme. It is separately implemented in Encode::Unicode::UTF7. For details see L
. =item Quick Reference Decodes from ord(N) Encodes chr(N) to... octet/char BOM S.P d800-dfff ord > 0xffff \x{1abcd} == ---------------+-----------------+------------------------------ UCS-2BE 2 N N is bogus Not Available UCS-2LE 2 N N bogus Not Available UTF-16 2/4 Y Y is S.P S.P BE/LE UTF-16BE 2/4 N Y S.P S.P 0xd82a,0xdfcd UTF-16LE 2/4 N Y S.P S.P 0x2ad8,0xcddf UTF-32 4 Y - is bogus As is BE/LE UTF-32BE 4 N - bogus As is 0x0001abcd UTF-32LE 4 N - bogus As is 0xcdab0100 UTF-8 1-4 - - bogus >= 4 octets \xf0\x9a\af\8d ---------------+-----------------+------------------------------ =back =head1 Size, Endianness, and BOM You can categorize these CES by 3 criteria: size of each character, endianness, and Byte Order Mark. =head2 by size UCS-2 is a fixed-length encoding with each character taking 16 bits. It B
support I
. When a surrogate pair is encountered during decode(), its place is filled with \x{FFFD} if I
is 0, or the routine croaks if I
is 1. When a character whose ord value is larger than 0xFFFF is encountered, its place is filled with \x{FFFD} if I
is 0, or the routine croaks if I
is 1. UTF-16 is almost the same as UCS-2 but it supports I
. When it encounters a high surrogate (0xD800-0xDBFF), it fetches the following low surrogate (0xDC00-0xDFFF) and C
s them to form a character. Bogus surrogates result in death. When \x{10000} or above is encountered during encode(), it C
s them and pushes the surrogate pair to the output stream. UTF-32 (UCS-4) is a fixed-length encoding with each character taking 32 bits. Since it is 32-bit, there is no need for I
. =head2 by endianness The first (and now failed) goal of Unicode was to map all character repertoires into a fixed-length integer so that programmers are happy. Since each character is either a I
or I
in C, you have to pay attention to the endianness of each platform when you pass data to one another. Anything marked as BE is Big Endian (or network byte order) and LE is Little Endian (aka VAX byte order). For anything not marked either BE or LE, a character called Byte Order Mark (BOM) indicating the endianness is prepended to the string. CAVEAT: Though BOM in utf8 (\xEF\xBB\xBF) is valid, it is meaningless and as of this writing Encode suite just leave it as is (\x{FeFF}). =over 4 =item BOM as integer when fetched in network byte order 16 32 bits/char ------------------------- BE 0xFeFF 0x0000FeFF LE 0xFFFe 0xFFFe0000 ------------------------- =back This modules handles the BOM as follows. =over 4 =item * When BE or LE is explicitly stated as the name of encoding, BOM is simply treated as a normal character (ZERO WIDTH NO-BREAK SPACE). =item * When BE or LE is omitted during decode(), it checks if BOM is at the beginning of the string; if one is found, the endianness is set to what the BOM says. =item * Default Byte Order When no BOM is found, Encode 2.76 and blow croaked. Since Encode 2.77, it falls back to BE accordingly to RFC2781 and the Unicode Standard version 8.0 =item * When BE or LE is omitted during encode(), it returns a BE-encoded string with BOM prepended. So when you want to encode a whole text file, make sure you encode() the whole text at once, not line by line or each line, not file, will have a BOM prepended. =item * C
is an exception. Unlike others, this is an alias of UCS-2BE. UCS-2 is already registered by IANA and others that way. =back =head1 Surrogate Pairs To say the least, surrogate pairs were the biggest mistake of the Unicode Consortium. But according to the late Douglas Adams in I
Trilogy, C
. Their mistake was not of this magnitude so let's forgive them. (I don't dare make any comparison with Unicode Consortium and the Vogons here ;) Or, comparing Encode to Babel Fish is completely appropriate -- if you can only stick this into your ear :) Surrogate pairs were born when the Unicode Consortium finally admitted that 16 bits were not big enough to hold all the world's character repertoires. But they already made UCS-2 16-bit. What do we do? Back then, the range 0xD800-0xDFFF was not allocated. Let's split that range in half and use the first half to represent the C
and the second half to represent the C
. That way, you can represent 1024 * 1024 = 1048576 more characters. Now we can store character ranges up to \x{10ffff} even with 16-bit encodings. This pair of half-character is now called a I
and UTF-16 is the name of the encoding that embraces them. Here is a formula to ensurrogate a Unicode character \x{10000} and above; $hi = ($uni - 0x10000) / 0x400 + 0xD800; $lo = ($uni - 0x10000) % 0x400 + 0xDC00; And to desurrogate; $uni = 0x10000 + ($hi - 0xD800) * 0x400 + ($lo - 0xDC00); Note this move has made \x{D800}-\x{DFFF} into a forbidden zone but perl does not prohibit the use of characters within this range. To perl, every one of \x{0000_0000} up to \x{ffff_ffff} (*) is I
. (*) or \x{ffff_ffff_ffff_ffff} if your perl is compiled with 64-bit integer support! =head1 Error Checking Unlike most encodings which accept various ways to handle errors, Unicode encodings simply croaks. % perl -MEncode -e'$_ = "\xfe\xff\xd8\xd9\xda\xdb\0\n"' \ -e'Encode::from_to($_, "utf16","shift_jis", 0); print' UTF-16:Malformed LO surrogate d8d9 at /path/to/Encode.pm line 184. % perl -MEncode -e'$a = "BOM missing"' \ -e' Encode::from_to($a, "utf16", "shift_jis", 0); print' UTF-16:Unrecognised BOM 424f at /path/to/Encode.pm line 184. Unlike other encodings where mappings are not one-to-one against Unicode, UTFs are supposed to map 100% against one another. So Encode is more strict on UTFs. Consider that "division by zero" of Encode :) =head1 SEE ALSO L
, L
, L
, L
, RFC 2781 L
, The whole Unicode standard L
Ch. 15, pp. 403 of C
by Larry Wall, Tom Christiansen, Jon Orwant; O'Reilly & Associates; ISBN 0-596-00027-8 =cut PK #\1-) ) README.e2xnu [ Encode::$_Name_ version 0.1 ======== NAME Encode::$_Name_ -
SYNOPSIS use Encode::$_Name_; #
ABSTRACT
INSTALLATION To install this module type the following: perl Makefile.PL make make test make install DEPENDENCIES This module requires perl version 5.7.3 or later. COPYRIGHT AND LICENCE Copyright (C) 2002 Your Name
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. PK #\kQA CN/HZ.pmnu [ package Encode::CN::HZ; use strict; use warnings; use utf8 (); use vars qw($VERSION); $VERSION = do { my @r = ( q$Revision: 2.10 $ =~ /\d+/g ); sprintf "%d." . "%02d" x $#r, @r }; use Encode qw(:fallbacks); use parent qw(Encode::Encoding); __PACKAGE__->Define('hz'); # HZ is a combination of ASCII and escaped GB, so we implement it # with the GB2312(raw) encoding here. Cf. RFCs 1842 & 1843. # not ported for EBCDIC. Which should be used, "~" or "\x7E"? sub needs_lines { 1 } sub decode ($$;$) { my ( $obj, $str, $chk ) = @_; return undef unless defined $str; my $GB = Encode::find_encoding('gb2312-raw'); my $ret = substr($str, 0, 0); # to propagate taintedness my $in_ascii = 1; # default mode is ASCII. while ( length $str ) { if ($in_ascii) { # ASCII mode if ( $str =~ s/^([\x00-\x7D\x7F]+)// ) { # no '~' => ASCII $ret .= $1; # EBCDIC should need ascii2native, but not ported. } elsif ( $str =~ s/^\x7E\x7E// ) { # escaped tilde $ret .= '~'; } elsif ( $str =~ s/^\x7E\cJ// ) { # '\cJ' == LF in ASCII 1; # no-op } elsif ( $str =~ s/^\x7E\x7B// ) { # '~{' $in_ascii = 0; # to GB } else { # encounters an invalid escape, \x80 or greater last; } } else { # GB mode; the byte ranges are as in RFC 1843. no warnings 'uninitialized'; if ( $str =~ s/^((?:[\x21-\x77][\x21-\x7E])+)// ) { my $prefix = $1; $ret .= $GB->decode( $prefix, $chk ); } elsif ( $str =~ s/^\x7E\x7D// ) { # '~}' $in_ascii = 1; } else { # invalid last; } } } $_[1] = '' if $chk; # needs_lines guarantees no partial character return $ret; } sub cat_decode { my ( $obj, undef, $src, $pos, $trm, $chk ) = @_; my ( $rdst, $rsrc, $rpos ) = \@_[ 1 .. 3 ]; my $GB = Encode::find_encoding('gb2312-raw'); my $ret = ''; my $in_ascii = 1; # default mode is ASCII. my $ini_pos = pos($$rsrc); substr( $src, 0, $pos ) = ''; my $ini_len = bytes::length($src); # $trm is the first of the pair '~~', then 2nd tilde is to be removed. # XXX: Is better C<$src =~ s/^\x7E// or die if ...>? $src =~ s/^\x7E// if $trm eq "\x7E"; while ( length $src ) { my $now; if ($in_ascii) { # ASCII mode if ( $src =~ s/^([\x00-\x7D\x7F])// ) { # no '~' => ASCII $now = $1; } elsif ( $src =~ s/^\x7E\x7E// ) { # escaped tilde $now = '~'; } elsif ( $src =~ s/^\x7E\cJ// ) { # '\cJ' == LF in ASCII next; } elsif ( $src =~ s/^\x7E\x7B// ) { # '~{' $in_ascii = 0; # to GB next; } else { # encounters an invalid escape, \x80 or greater last; } } else { # GB mode; the byte ranges are as in RFC 1843. if ( $src =~ s/^((?:[\x21-\x77][\x21-\x7F])+)// ) { $now = $GB->decode( $1, $chk ); } elsif ( $src =~ s/^\x7E\x7D// ) { # '~}' $in_ascii = 1; next; } else { # invalid last; } } next if !defined $now; $ret .= $now; if ( $now eq $trm ) { $$rdst .= $ret; $$rpos = $ini_pos + $pos + $ini_len - bytes::length($src); pos($$rsrc) = $ini_pos; return 1; } } $$rdst .= $ret; $$rpos = $ini_pos + $pos + $ini_len - bytes::length($src); pos($$rsrc) = $ini_pos; return ''; # terminator not found } sub encode($$;$) { my ( $obj, $str, $chk ) = @_; return undef unless defined $str; my $GB = Encode::find_encoding('gb2312-raw'); my $ret = substr($str, 0, 0); # to propagate taintedness; my $in_ascii = 1; # default mode is ASCII. no warnings 'utf8'; # $str may be malformed UTF8 at the end of a chunk. while ( length $str ) { if ( $str =~ s/^([[:ascii:]]+)// ) { my $tmp = $1; $tmp =~ s/~/~~/g; # escapes tildes if ( !$in_ascii ) { $ret .= "\x7E\x7D"; # '~}' $in_ascii = 1; } $ret .= pack 'a*', $tmp; # remove UTF8 flag. } elsif ( $str =~ s/(.)// ) { my $s = $1; my $tmp = $GB->encode( $s, $chk || 0 ); last if !defined $tmp; if ( length $tmp == 2 ) { # maybe a valid GB char (XXX) if ($in_ascii) { $ret .= "\x7E\x7B"; # '~{' $in_ascii = 0; } $ret .= $tmp; } elsif ( length $tmp ) { # maybe FALLBACK in ASCII (XXX) if ( !$in_ascii ) { $ret .= "\x7E\x7D"; # '~}' $in_ascii = 1; } $ret .= $tmp; } } else { # if $str is malformed UTF8 *and* if length $str != 0. last; } } $_[1] = $str if $chk; # The state at the end of the chunk is discarded, even if in GB mode. # That results in the combination of GB-OUT and GB-IN, i.e. "~}~{". # Parhaps it is harmless, but further investigations may be required... if ( !$in_ascii ) { $ret .= "\x7E\x7D"; # '~}' $in_ascii = 1; } utf8::encode($ret); # https://rt.cpan.org/Ticket/Display.html?id=35120 return $ret; } 1; __END__ =head1 NAME Encode::CN::HZ -- internally used by Encode::CN =cut PK #\p PerlIO.podnu [ =head1 NAME Encode::PerlIO -- a detailed document on Encode and PerlIO =head1 Overview It is very common to want to do encoding transformations when reading or writing files, network connections, pipes etc. If Perl is configured to use the new 'perlio' IO system then C
provides a "layer" (see L
) which can transform data as it is read or written. Here is how the blind poet would modernise the encoding: use Encode; open(my $iliad,'<:encoding(iso-8859-7)','iliad.greek'); open(my $utf8,'>:utf8','iliad.utf8'); my @epic = <$iliad>; print $utf8 @epic; close($utf8); close($illiad); In addition, the new IO system can also be configured to read/write UTF-8 encoded characters (as noted above, this is efficient): open(my $fh,'>:utf8','anything'); print $fh "Any \x{0021} string \N{SMILEY FACE}\n"; Either of the above forms of "layer" specifications can be made the default for a lexical scope with the C
pragma. See L
. Once a handle is open, its layers can be altered using C
. Without any such configuration, or if Perl itself is built using the system's own IO, then write operations assume that the file handle accepts only I
and will C
if a character larger than 255 is written to the handle. When reading, each octet from the handle becomes a byte-in-a-character. Note that this default is the same behaviour as bytes-only languages (including Perl before v5.6) would have, and is sufficient to handle native 8-bit encodings e.g. iso-8859-1, EBCDIC etc. and any legacy mechanisms for handling other encodings and binary data. In other cases, it is the program's responsibility to transform characters into bytes using the API above before doing writes, and to transform the bytes read from a handle into characters before doing "character operations" (e.g. C
, C\W+/>, ...). You can also use PerlIO to convert larger amounts of data you don't want to bring into memory. For example, to convert between ISO-8859-1 (Latin 1) and UTF-8 (or UTF-EBCDIC in EBCDIC machines): open(F, "<:encoding(iso-8859-1)", "data.txt") or die $!; open(G, ">:utf8", "data.utf") or die $!; while (
) { print G } # Could also do "print G
" but that would pull # the whole file into memory just to write it out again. More examples: open(my $f, "<:encoding(cp1252)") open(my $g, ">:encoding(iso-8859-2)") open(my $h, ">:encoding(latin9)") # iso-8859-15 See also L
for how to change the default encoding of the data in your script. =head1 How does it work? Here is a crude diagram of how filehandle, PerlIO, and Encode interact. filehandle <-> PerlIO PerlIO <-> scalar (read/printed) \ / Encode When PerlIO receives data from either direction, it fills a buffer (currently with 1024 bytes) and passes the buffer to Encode. Encode tries to convert the valid part and passes it back to PerlIO, leaving invalid parts (usually a partial character) in the buffer. PerlIO then appends more data to the buffer, calls Encode again, and so on until the data stream ends. To do so, PerlIO always calls (de|en)code methods with CHECK set to 1. This ensures that the method stops at the right place when it encounters partial character. The following is what happens when PerlIO and Encode tries to encode (from utf8) more than 1024 bytes and the buffer boundary happens to be in the middle of a character. A B C .... ~ \x{3000} .... 41 42 43 .... 7E e3 80 80 .... <- buffer ---------------> << encoded >>>>>>>>>> <- next buffer ------ Encode converts from the beginning to \x7E, leaving \xe3 in the buffer because it is invalid (partial character). Unfortunately, this scheme does not work well with escape-based encodings such as ISO-2022-JP. =head1 Line Buffering Now let's see what happens when you try to decode from ISO-2022-JP and the buffer ends in the middle of a character. JIS208-ESC \x{5f3e} A B C .... ~ \e $ B |DAN | .... 41 42 43 .... 7E 1b 24 41 43 46 .... <- buffer ---------------------------> << encoded >>>>>>>>>>>>>>>>>>>>>>> As you see, the next buffer begins with \x43. But \x43 is 'C' in ASCII, which is wrong in this case because we are now in JISX 0208 area so it has to convert \x43\x46, not \x43. Unlike utf8 and EUC, in escape-based encodings you can't tell if a given octet is a whole character or just part of it. Fortunately PerlIO also supports line buffer if you tell PerlIO to use one instead of fixed buffer. Since ISO-2022-JP is guaranteed to revert to ASCII at the end of the line, partial character will never happen when line buffer is used. To tell PerlIO to use line buffer, implement -E
needs_lines method for your encoding object. See L
for details. Thanks to these efforts most encodings that come with Encode support PerlIO but that still leaves following encodings. iso-2022-kr MIME-B MIME-Header MIME-Q Fortunately iso-2022-kr is hardly used (according to Jungshik) and MIME-* are very unlikely to be fed to PerlIO because they are for mail headers. See L
for details. =head2 How can I tell whether my encoding fully supports PerlIO ? As of this writing, any encoding whose class belongs to Encode::XS and Encode::Unicode works. The Encode module has a C
method which you can use before applying PerlIO encoding to the filehandle. Here is an example: my $use_perlio = perlio_ok($enc); my $layer = $use_perlio ? "<:raw" : "<:encoding($enc)"; open my $fh, $layer, $file or die "$file : $!"; while(<$fh>){ $_ = decode($enc, $_) unless $use_perlio; # .... } =head1 SEE ALSO L
, L
, L
, L
, L
, L
, L
, L
, the Perl Unicode Mailing List E
perl-unicode@perl.orgE
=cut PK #\#