Integrate mainline
[p5sagit/p5-mst-13.2.git] / ext / Encode / lib / Encode / Tcl / Table.pm
1 package Encode::Tcl::Table;
2 use strict;
3 our $VERSION = do {my @r=(q$Revision: 1.1 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r};
4 use base 'Encode::Encoding';
5
6 use Carp;
7 #use Data::Dumper;
8
9 sub read
10 {
11     my ($obj,$fh,$name,$type) = @_;
12     my($rep, @leading);
13     my ($def,$sym,$pages) = split(/\s+/,scalar(<$fh>));
14     my @touni;
15     my %fmuni;
16     my $count = 0;
17     $def = hex($def);
18     while ($pages--)
19     {
20         my $line = <$fh>;
21         chomp($line);
22         my $page = hex($line);
23         my @page;
24         $leading[$page] = 1 if $page;
25         my $ch = $page * 256;
26         for (my $i = 0; $i < 16; $i++)
27         {
28             my $line = <$fh>;
29             for (my $j = 0; $j < 16; $j++)
30             {
31                 my $val = hex(substr($line,0,4,''));
32                 if ($val || !$ch)
33                 {
34                     my $uch = pack('U', $val); # chr($val);
35                     push(@page,$uch);
36                     $fmuni{$uch} = $ch;
37                     $count++;
38                 }
39                 else
40                 {
41                     push(@page,undef);
42                 }
43                 $ch++;
44             }
45         }
46         $touni[$page] = \@page;
47     }
48     $rep = $type ne 'M'
49         ? $obj->can("rep_$type")
50             : sub
51             {
52                 ($_[0] > 255) || $leading[$_[0]] ? 'n' : 'C';
53             };
54     $obj->{'Rep'}   = $rep;
55     $obj->{'ToUni'} = \@touni;
56     $obj->{'FmUni'} = \%fmuni;
57     $obj->{'Def'}   = $def;
58     $obj->{'Num'}   = $count;
59     return $obj;
60 }
61
62 sub rep_S { 'C' }
63
64 sub rep_D { 'n' }
65
66 #sub rep_M { ($_[0] > 255) ? 'n' : 'C' }
67
68 sub representation
69 {
70     my ($obj,$ch) = @_;
71     $ch = 0 unless @_ > 1;
72     $obj->{'Rep'}->($ch);
73 }
74
75 sub decode
76 {
77     my($obj,$str,$chk) = @_;
78     my $name  = $obj->{'Name'};
79     my $rep   = $obj->{'Rep'};
80     my $touni = $obj->{'ToUni'};
81     my $uni;
82     while (length($str))
83     {
84         my $cc = substr($str,0,1,'');
85         my $ch = ord($cc);
86         my $x;
87         if (&$rep($ch) eq 'C')
88         {
89             $x = $touni->[0][$ch];
90         }
91         else
92         {
93             if(! length $str)
94             {
95                 $str = pack('C',$ch); # split leading byte
96                 last;
97             }
98             my $c2 = substr($str,0,1,'');
99             $cc .= $c2;
100             $x = $touni->[$ch][ord($c2)];
101         }
102         unless (defined $x)
103         {
104           Encode::Tcl::no_map_in_decode($name, $cc.$str);
105         }
106         $uni .= $x;
107     }
108     $_[1] = $str if $chk;
109     return $uni;
110 }
111
112
113 sub encode
114 {
115     my ($obj,$uni,$chk) = @_;
116     my $fmuni = $obj->{'FmUni'};
117     my $def   = $obj->{'Def'};
118     my $name  = $obj->{'Name'};
119     my $rep   = $obj->{'Rep'};
120     my $str;
121     while (length($uni))
122     {
123         my $ch = substr($uni,0,1,'');
124         my $x  = $fmuni->{$ch};
125         unless(defined $x)
126         {
127             unless($chk)
128             {
129               Encode::Tcl::no_map_in_encode(ord($ch), $name)
130               }
131             return undef;
132         }
133         $str .= pack(&$rep($x),$x);
134     }
135     $_[1] = $uni if $chk;
136     return $str;
137 }
138 1;
139 __END__