File Coverage

blib/lib/Encode/JP/Mobile/KDDIJIS.pm
Criterion Covered Total %
statement 119 121 98.3
branch 39 44 88.6
condition 10 15 66.6
subroutine 22 22 100.0
pod 2 2 100.0
total 192 204 94.1


line stmt bran cond sub pod time code
1             package Encode::JP::Mobile::KDDIJIS;
2 24     24   141 use strict;
  24         57  
  24         1036  
3 24     24   154 use warnings;
  24         49  
  24         1195  
4 24     24   140 use base qw(Encode::Encoding);
  24         47  
  24         6917  
5 24     24   158 use Encode::Alias;
  24         53  
  24         1714  
6 24     24   32254 use Encode::CJKConstants qw(:all);
  24         18555  
  24         4224  
7 24     24   156 use Encode qw(:fallbacks);
  24         65  
  24         4469  
8 24     24   145 use Encode::JP::Mobile;
  24         52  
  24         1046  
9 24     24   24192 use POSIX 'ceil';
  24         260220  
  24         183  
10 24     24   52102 use Carp;
  24         56  
  24         11434  
11              
12             define_alias('x-iso-2022-jp-ezweb' => 'x-iso-2022-jp-kddi');
13             __PACKAGE__->Define(qw(x-iso-2022-jp-kddi));
14              
15             my $re_scan_jis = qr{
16             (?:($RE{JIS_0212})|$RE{JIS_0208}|($RE{ISO_ASC})|($RE{JIS_KANA}))([^\e]*)
17             }x;
18              
19             sub _encoding() { 'x-sjis-kddi-cp932-raw' }
20              
21             sub decode($$;$) {
22 27     27 1 28737 my ($self, $str, $chk) = @_;
23              
24 27         54 my $residue = '';
25 27 100       78 if ($chk) {
26 1 50       6 $str =~ s/([^\x00-\x7f].*)$//so and $residue = $1;
27             }
28 27         70 $residue .= _jis_sjis( \$str );
29 27 100       74 $_[1] = $residue if $chk;
30              
31 27         183 return Encode::decode( $self->_encoding, $str, FB_PERLQQ );
32             }
33              
34             sub encode($$;$) {
35 25     25 1 10938 my ( $obj, $utf8, $chk ) = @_;
36 25         113 my $octet = Encode::encode( $obj->_encoding, $utf8, $chk );
37 25         575 return _sjis_jis( $octet );
38             }
39              
40             sub ASC () { 1 }
41             sub JIS_0208 () { 2 }
42             sub KANA () { 3 }
43             sub _sjis_jis {
44 25     25   39 my $octet = shift;
45              
46 24     24   205 use bytes;
  24         47  
  24         209  
47              
48 25         240 my @chars = split //, $octet;
49 25         52 my $mode = ASC;
50 25         38 my $res = '';
51              
52 25         79 for (my $i=0; $i<@chars; $i++) {
53 109         144 my $x = ord $chars[$i];
54 109 100 100     347 if ($x < 0x80) {
    100          
55 21 100       45 if ($mode != ASC) {
56 3         9 $res .= $ESC{ASC};
57 3         6 $mode = ASC;
58             }
59 21         57 $res .= chr $x;
60             } elsif (0xA1 <= $x && $x <= 0xDF) {
61 12 100       28 if ($mode != KANA) {
62 3         6 $res .= $ESC{KANA};
63 3         6 $mode = KANA;
64             }
65 12         13 $mode = KANA;
66 12         34 $res .= chr($x - 0x80);
67             } else {
68 76 100       141 if ($mode != JIS_0208) {
69 22         48 $res .= $ESC{JIS_0208};
70 22         27 $mode = JIS_0208;
71             }
72 76         73 $i++;
73 76 50       149 last unless $i<@chars;
74 76         157 my ($c1, $c2) = _sjis2jis_one($x, ord $chars[$i]);
75 76         265 $res .= chr($c1).chr($c2);
76             }
77             }
78              
79 25 100       61 if ($mode != ASC) {
80 22         35 $res .= $ESC{ASC};
81             }
82              
83 25         120 $res;
84             }
85             sub _sjis2jis_one {
86 76     76   93 my ($c1, $c2) = @_;
87              
88             # 0x0600 : 0xF340 - 0xF48D
89             # 0x0B00 : 0xF640 - 0xF7FC
90              
91 76         97 my $c = ($c1<<8) + $c2;
92 76 50 66     366 if (0xF340 <= $c && $c <= 0xF48D) {
    100 66        
93 0         0 $c1 -= 0x06;
94             } elsif (0xF640 <= $c && $c <= 0xF7FC) {
95 12         20 $c1 -= 0x0B;
96             }
97              
98 76 100       135 $c1 -= ($c1 <= 0x9f) ? 0x71 : 0xB1;
99 76         90 $c1 = $c1*2 + 1;
100              
101 76 100       141 if ($c2 > 0x7F) {
102 49         55 $c2 -= 0x01;
103             }
104              
105 76 100       121 if ($c2>=0x9E) {
106 49         51 $c2 = $c2-0x7D;
107 49         57 $c1++;
108             } else {
109 27         31 $c2 -= 0x1F;
110             }
111              
112 76         132 return ($c1, $c2);
113             }
114              
115             sub _jis_sjis {
116 27     27   76 local ${^ENCODING};
117              
118 27         38 my $r_str = shift;
119 27         173 $$r_str =~ s($re_scan_jis){
120 52         169 my ($esc_0212, $esc_asc, $esc_kana, $chunk) = ($1, $2, $3, $4);
121              
122 52 100       148 if ($esc_kana) {
    100          
123 3         111 $chunk =~ s{(.)}{
124 12         67 pack "H*", sprintf "%X", (0x80 + (hex unpack "H*", $1));
125             }geox;
126 3         17 $chunk;
127             } elsif ($esc_asc) {
128 26         265 $chunk;
129             } else {
130 23         84 $chunk =~ s((..)){
131 79         327 pack "H*", sprintf"%X", _jis2sjis_one(hex(unpack "H*", $1));
132             }geox;
133 23         215 $chunk;
134             }
135              
136             }geox;
137              
138 27         79 my ($residue) = ( $$r_str =~ s/(\e.*)$//so );
139              
140 27         99 return $residue;
141             }
142              
143 79     79   108 sub _jis2sjis_one { my $x = shift; return ( _xy($x) << 8 ) + _zu($x) } # input is binary
  79         142  
144              
145 158     158   172 sub _high { my $x = shift; $x >> 8 }
  158         263  
146 79     79   92 sub _low { my $x = shift; $x & 0xff }
  79         127  
147              
148             sub _xy {
149 79     79   89 my $jis = shift;
150              
151 79         131 my $pq = _high($jis);
152 79         259 my $t = ceil( $pq / 2 ) + 0x70;
153 79 100       159 my $ans = ($t <= 0x9F) ? $t : $t+0x40;
154              
155             # XXX !!!
156 79 50 33     509 if (0xED == $ans || $ans == 0xEE) {
    100 66        
157 0         0 return $ans + 0x06;
158             } elsif (0xEB == $ans || $ans == 0xEC) {
159 13         45 return $ans + 0x0b;
160             } else {
161 66         169 return $ans;
162             }
163             }
164              
165             sub _zu {
166 79     79   94 my $jis = shift;
167 79         139 my $pq = _high($jis);
168 79         137 my $rs = _low($jis);
169              
170 79 100       161 if ( $pq % 2 ) { # odd
171 28         33 my $t = $rs + 0x20;
172 28 50       191 return ( $t > 0x7f ) ? $t : $t - 1;
173             }
174             else { # even
175 51         289 return $rs + 0x7E;
176             }
177             }
178              
179             package # hide from PAUSE
180             Encode::JP::Mobile::KDDIJIS::Auto;
181 24     24   28354 use base 'Encode::JP::Mobile::KDDIJIS';
  24         54  
  24         3025  
182 24     24   167 use Encode::Alias;
  24         53  
  24         2998  
183              
184             define_alias('x-iso-2022-jp-ezweb-auto' => 'x-iso-2022-jp-kddi-auto');
185             __PACKAGE__->Define(qw(x-iso-2022-jp-kddi-auto));
186              
187             sub _encoding() { 'x-sjis-kddi-auto-raw' }
188              
189             1;
190              
191             __END__