Parent Directory
|
Revision Log
|
Patch
| revision 1.3 by wakaba, Mon Sep 16 02:20:18 2002 UTC | revision 1.7 by wakaba, Sun Sep 22 11:09:38 2002 UTC | |
|---|---|---|
| # | Line 3 | Line 3 |
| 3 | ||
| 4 | Encode::ISO2022 --- ISO/IEC 2022 encoder and decoder | Encode::ISO2022 --- ISO/IEC 2022 encoder and decoder |
| 5 | ||
| 6 | =head1 ENCODINGS | |
| 7 | ||
| 8 | =over 4 | |
| 9 | ||
| 10 | =item iso2022 | |
| 11 | ||
| 12 | ISO/IEC 2022:1994. Default status is: | |
| 13 | ||
| 14 | =over 2 | |
| 15 | ||
| 16 | =item CL = C0 = ISO/IEC 6429:1991 C0 set | |
| 17 | ||
| 18 | =item CR = C1 = ISO/IEC 6429:1991 C1 set | |
| 19 | ||
| 20 | =item GL = G0 = ISO/IEC 646:1991 IRV GL(G0) set | |
| 21 | ||
| 22 | =item GR = G1 = empty set | |
| 23 | ||
| 24 | =item G2 = empty set | |
| 25 | ||
| 26 | =item G3 = empty set | |
| 27 | ||
| 28 | =back | |
| 29 | ||
| 30 | (Alias: iso/iec2022, iso-2022, 2022, cp2022) | |
| 31 | ||
| 32 | =back | |
| 33 | ||
| 34 | Note that ISO/IEC 2022 based encodings are found in | |
| 35 | Encode::ISO2022::* modules. This module, Encode::ISO2022 | |
| 36 | only provides a general ISO/IEC 2022 encoder/decoder. | |
| 37 | ||
| 38 | =cut | =cut |
| 39 | ||
| 40 | require v5.7.3; | require v5.7.3; |
| 41 | package Encode::ISO2022; | package Encode::ISO2022; |
| 42 | use strict; | use strict; |
| 43 | use vars qw(%CHARSET $VERSION); | use vars qw(%CHARSET %CODING_SYSTEM $VERSION); |
| 44 | $VERSION=do{my @r=(q$Revision$=~/\d+/g);sprintf "%d."."%02d" x $#r,@r}; | $VERSION=do{my @r=(q$Revision$=~/\d+/g);sprintf "%d."."%02d" x $#r,@r}; |
| 45 | use base qw(Encode::Encoding); | use base qw(Encode::Encoding); |
| 46 | __PACKAGE__->Define (qw/iso-2022 iso2022 2022 cp2022/); | __PACKAGE__->Define (qw!iso-2022 iso/iec2022 iso2022 2022 cp2022!); |
| 47 | require Encode::Charset; | |
| 48 | *CHARSET = \%Encode::Charset::CHARSET; | |
| 49 | *CODING_SYSTEM = \%Encode::Charset::CODING_SYSTEM; | |
| 50 | ||
| 51 | ### --- Intialization | ### --- Intialization |
| 52 | ||
| # | Line 30 my %_CHARS_to_RANGE = ( | Line 65 my %_CHARS_to_RANGE = ( |
| 65 | b256 => q/[\x00-\xFF]/, | b256 => q/[\x00-\xFF]/, |
| 66 | ); | ); |
| 67 | ||
| ## --- Make initial charset definitions | ||
| &_make_initial_charsets; | ||
| sub _make_initial_charsets () { | ||
| for my $f (0x30..0x7E) { | ||
| my $F = pack 'C', $f; | ||
| for ('', '!', '"', '#') { | ||
| $CHARSET{G94}->{ $_.$F }->{dimension} = 1; | ||
| $CHARSET{G94}->{ $_.$F }->{chars} = 94; | ||
| $CHARSET{G94}->{ $_.$F }->{ucs} = | ||
| {'' => 0xE90940, '!' => 0xE944A0, '"' => 0xE98000, '#' => 0xE9BB60}->{ $_ } | ||
| + 94 * ($f-0x30); | ||
| $CHARSET{G96}->{ $_.$F }->{dimension} = 1; | ||
| $CHARSET{G96}->{ $_.$F }->{chars} = 96; | ||
| $CHARSET{G96}->{ $_.$F }->{ucs} = | ||
| {'' => 0xE926A0, '!' => 0xE96200, '"' => 0xE99D60, '#' => 0xE9D8C0}->{ $_ } | ||
| + 96 * ($f-0x30); | ||
| $CHARSET{C0}->{ $_.$F }->{dimension} = 1; | ||
| $CHARSET{C0}->{ $_.$F }->{chars} = 32; | ||
| $CHARSET{C0}->{ $_.$F }->{ucs} = | ||
| {'' => 0x70000000, '!' => 0x70001400, | ||
| '"' => 0x70002800, '#' => 0x70003C00}->{ $_ } + 32 * ($f-0x30); | ||
| $CHARSET{C1}->{ $_.$F }->{dimension} = 1; | ||
| $CHARSET{C1}->{ $_.$F }->{chars} = 32; | ||
| $CHARSET{C1}->{ $_.$F }->{ucs} = | ||
| {'' => 0x70000A00, '!' => 0x70001E00, | ||
| '"' => 0x70003200, '#' => 0x70004600}->{ $_ } + 32 * ($f-0x30); | ||
| $CHARSET{G94}->{ ' '.$_.$F }->{dimension} = 1; ## DRCS | ||
| $CHARSET{G94}->{ ' '.$_.$F }->{chars} = 94; | ||
| $CHARSET{G94}->{ ' '.$_.$F }->{ucs} = | ||
| {'' => 0x70090940, '!' => 0x700944A0, | ||
| '"' => 0x70098000, '#' => 0x7009BB60}->{ $_ } + 94 * ($f-0x30); | ||
| $CHARSET{G96}->{ ' '.$_.$F }->{dimension} = 1; ## DRCS | ||
| $CHARSET{G96}->{ ' '.$_.$F }->{chars} = 96; | ||
| $CHARSET{G96}->{ ' '.$_.$F }->{ucs} = | ||
| {'' => 0x700926A0, '!' => 0x70096200, | ||
| '"' => 0x70099D60, '#' => 0x7009D8C0}->{ $_ } + 96 * ($f-0x30); | ||
| } | ||
| } | ||
| for my $f (0x30..0x5F, 0x7E) { | ||
| my $F = pack 'C', $f; | ||
| for ('', '!', '"', '#', ' ') { | ||
| $CHARSET{G94n}->{ $_.$F }->{dimension} = 2; | ||
| $CHARSET{G94n}->{ $_.$F }->{chars} = 94; | ||
| $CHARSET{G94n}->{ $_.$F }->{ucs} = | ||
| ({'' => 0xE9F6C0}->{ $_ }||0) + 94*94 * ($f-0x30); | ||
| ## BUG: 94^n sets with I byte have no mapping area | ||
| $CHARSET{G96n}->{ $_.$F }->{dimension} = 2; | ||
| $CHARSET{G96n}->{ $_.$F }->{chars} = 96; | ||
| $CHARSET{G96n}->{ $_.$F }->{ucs} = | ||
| ({'' => 0xF4C000}->{ $_ }||0) + 96*96 * ($f-0x30); | ||
| ## BUG: 94^n DRCSes with I byte have no mapping area | ||
| } | ||
| } | ||
| for (0x60..0x6F) { | ||
| my $F = pack 'C', $_; | ||
| ## BUG: 9x^3 sets have no mapping area | ||
| for ('', '!', '"', '#', ' ') { | ||
| $CHARSET{G94n}->{ $_.$F }->{dimension} = 3; | ||
| $CHARSET{G94n}->{ $_.$F }->{chars} = 94; | ||
| $CHARSET{G96n}->{ $_.$F }->{dimension} = 3; | ||
| $CHARSET{G96n}->{ $_.$F }->{chars} = 96; | ||
| } | ||
| } | ||
| for (0x70..0x7D) { | ||
| my $F = pack 'C', $_; | ||
| ## BUG: 9x^4 sets have no mapping area | ||
| for ('', '!', '"', '#', ' ') { | ||
| $CHARSET{G94n}->{ $_.$F }->{dimension} = 4; | ||
| $CHARSET{G94n}->{ $_.$F }->{chars} = 94; | ||
| $CHARSET{G96n}->{ $_.$F }->{dimension} = 4; | ||
| $CHARSET{G96n}->{ $_.$F }->{chars} = 96; | ||
| } | ||
| } | ||
| for my $f (0x40..0x4E) { | ||
| my $F = pack 'C', $f; | ||
| $CHARSET{G96n}->{ ' '.$F }->{dimension} = 2; | ||
| $CHARSET{G96n}->{ ' '.$F }->{chars} = 96; | ||
| $CHARSET{G96n}->{ ' '.$F }->{ucs} = 0xF0000 + 96*96*($f-0x40); | ||
| ## U+F0000-U+10F7FF (private) -> ESC 02/04 02/00 <I> (04/00-04/14) (DRCS) | ||
| } | ||
| $CHARSET{G94}->{B}->{ucs} = 0x21; ## ASCII | ||
| $CHARSET{G96}->{A}->{ucs} = 0xA0; ## ISO 8859-1 | ||
| $CHARSET{G94n}->{'B@'}->{dimension} = 2; ## JIS X 0208-1990 | ||
| $CHARSET{G94n}->{'B@'}->{chars} = 94; | ||
| $CHARSET{G94n}->{'B@'}->{ucs} = 0xE9F6C0 + 94*94*79; | ||
| ## -- Control character sets | ||
| $CHARSET{C0}->{'@'}->{ucs} = 0x00; ## ISO/IEC 6429 C0 | ||
| for ("\x40", "\x43", "\x44", "\x45", "\x46", "\x49", "\x4A", "\x4B", "\x4C") { | ||
| $CHARSET{C0}->{$_}->{C_LS0} = "\x0F"; | ||
| $CHARSET{C0}->{$_}->{C_LS1} = "\x0E"; | ||
| $CHARSET{C0}->{$_}->{r_LS0} = '\x0F'; | ||
| $CHARSET{C0}->{$_}->{r_LS1} = '\x0E'; | ||
| } | ||
| for ("\x40", "\x44", "\x45", "\x46", "\x48", "\x4C") { | ||
| $CHARSET{C0}->{$_}->{reset_all} = {"\x0A" => 1, "\x0B" => 1, | ||
| "\x0C" => 1, "\x0D" => 1}; | ||
| } | ||
| $CHARSET{C0}->{"\x43"}->{reset_all} = {"\x0A" => 1}; | ||
| $CHARSET{C0}->{"\x44"}->{C_SS2} = "\x1C"; | ||
| $CHARSET{C0}->{"\x44"}->{r_SS2} = '\x1C'; | ||
| for ("\x45", "\x49", "\x4A", "\x4B") { | ||
| $CHARSET{C0}->{$_}->{C_SS2} = "\x19"; | ||
| $CHARSET{C0}->{$_}->{C_SS3} = "\x1D"; | ||
| $CHARSET{C0}->{$_}->{r_SS2} = '\x19'; | ||
| $CHARSET{C0}->{$_}->{r_SS3} = '\x1D'; | ||
| } | ||
| $CHARSET{C0}->{"\x4C"}->{C_SS2} = "\x19"; | ||
| $CHARSET{C0}->{"\x4C"}->{r_SS2} = '\x19'; | ||
| $CHARSET{C1}->{'64291991C1'}->{dimension} = 1; ## ISO/IEC 6429:1991 C1 | ||
| $CHARSET{C1}->{'64291991C1'}->{chars} = 32; | ||
| $CHARSET{C1}->{'64291991C1'}->{ucs} = 0x80; | ||
| for ("\x43", "\x45", "\x47", '64291991C1') { | ||
| $CHARSET{C1}->{$_}->{C_SS2} = "\x8E"; | ||
| $CHARSET{C1}->{$_}->{C_SS3} = "\x8F"; | ||
| $CHARSET{C1}->{$_}->{r_SS2} = '\x8E'; | ||
| $CHARSET{C1}->{$_}->{r_SS3} = '\x8F'; | ||
| $CHARSET{C1}->{$_}->{r_SS2_ESC} = '\x1B\x4E'; | ||
| $CHARSET{C1}->{$_}->{r_SS3_ESC} = '\x1B\x4F'; | ||
| } | ||
| for ("\x43", '64291991C1') { | ||
| $CHARSET{C1}->{$_}->{r_CSI} = '\x9B'; | ||
| $CHARSET{C1}->{$_}->{r_CSI_ESC} = '\x1B\x5B'; | ||
| $CHARSET{C1}->{$_}->{r_DCS} = '\x90'; | ||
| $CHARSET{C1}->{$_}->{r_ST} = '\x9C'; | ||
| $CHARSET{C1}->{$_}->{r_OSC} = '\x9D'; | ||
| $CHARSET{C1}->{$_}->{r_PM} = '\x9E'; | ||
| $CHARSET{C1}->{$_}->{r_APC} = '\x9F'; | ||
| $CHARSET{C1}->{$_}->{reset_all} = {"\x85"=>1, "\x90"=>1, | ||
| "\x9C"=>1, "\x9D"=>1, "\x9E"=>1, "\x9F"=>1}; | ||
| } | ||
| $CHARSET{C1}->{'64291991C1'}->{r_SCI} = '\x9A'; | ||
| $CHARSET{single_control}->{Fs} ={ucs => 0x70005000, chars => 32, dimension => 1}; | ||
| $CHARSET{single_control}->{'3F'} ={ucs => 0x70005020, chars => 80, dimension => 1}; | ||
| $CHARSET{single_control}->{'3F!'}={ucs => 0x70005070, chars => 80, dimension => 1}; | ||
| $CHARSET{single_control}->{'3F"'}={ucs => 0x700050C0, chars => 80, dimension => 1}; | ||
| $CHARSET{single_control}->{'3F#'}={ucs => 0x70005110, chars => 80, dimension => 1}; | ||
| } | ||
| 68 | ### --- Perl Encode module common functions | ### --- Perl Encode module common functions |
| 69 | ||
| 70 | sub encode ($$;$) { | sub encode ($$;$) { |
| # | Line 198 sub decode ($$;$) { | Line 81 sub decode ($$;$) { |
| 81 | } | } |
| 82 | ||
| 83 | ### --- Encode::ISO2022 unique functions | ### --- Encode::ISO2022 unique functions |
| 84 | *new_object = \&Encode::Charset::new_object; | |
| 85 | ||
| 86 | ## Make a new ISO/IEC 2022-buffers object with default status | sub iso2022_to_internal ($;\%) { |
| 87 | sub new_object { | my ($s, $C) = @_; |
| 88 | my %C; | $C ||= &new_object; |
| 89 | $C{bit} = 8; | my $t = ''; |
| 90 | $C{CL} = 'C0'; $C{CR} = 'C1'; $C{ESC_Fe} = 'C1'; | $s =~ s{ |
| 91 | $C{C0} = $CHARSET{C0}->{"\x40"}; ## ISO/IEC 6429:1991 C0 | ^((?:(?!\x1B\x25\x2F?[\x30-\x7E]).)*) |
| 92 | $C{C1} = $CHARSET{C1}->{'64291991C1'}; ## ISO/IEC 6429:1991 C1 | }{ |
| 93 | $C{GL} = 'G0'; $C{GR} = 'G1'; | my $i2 = $1; |
| 94 | $C{G0} = $CHARSET{G94}->{"\x42"}; ## ISO/IEC 646:1991 IRV | $t = _iso2022_to_internal ($i2, $C); |
| 95 | #$C{G1} = $CHARSET{G96}->{"\x41"}; ## ISO/IEC 8859-1 GR | ''; |
| 96 | $C{G1} = $CHARSET{G94}->{"\x7E"}; ## empty set | }gesx; |
| 97 | $C{G2} = $CHARSET{G94}->{"\x7E"}; ## empty set | my $pad = ''; |
| 98 | $C{G3} = $CHARSET{G94}->{"\x7E"}; ## empty set | use re 'eval'; |
| 99 | $C{option} = { | $s =~ s{ |
| 100 | C1invoke_to_right => 0, ## C1 invoked to: (0: ESC Fe, 1: CR) | ## ISO/IEC 2022 |