File Coverage

blib/lib/Encode/JISX0213/CCS.pm
Criterion Covered Total %
statement 53 70 75.7
branch 20 36 55.5
condition 7 12 58.3
subroutine 7 8 87.5
pod 3 3 100.0
total 90 129 69.7


line stmt bran cond sub pod time code
1             #-*- perl -*-
2             #-*- coding: us-ascii -*-
3              
4             package Encode::JISX0213::CCS;
5              
6 2     2   12 use strict;
  2         4  
  2         104  
7 2     2   13 use warnings;
  2         4  
  2         87  
8 2     2   11 use base qw(Encode::Encoding);
  2         2  
  2         276  
9             our $VERSION = '0.03';
10              
11 2     2   15 use Carp qw(carp croak);
  2         4  
  2         219  
12 2     2   13 use XSLoader;
  2         4  
  2         3016  
13             XSLoader::load('Encode::JISX0213', $VERSION);
14              
15             my $err_encode_nomap = '"\x{%*v04X}" does not map to %s';
16              
17             my $DIE_ON_ERR = Encode::DIE_ON_ERR();
18             my $FB_QUIET = Encode::FB_QUIET();
19             my $HTMLCREF = Encode::HTMLCREF();
20             my $LEAVE_SRC = Encode::LEAVE_SRC();
21             my $PERLQQ = Encode::PERLQQ();
22             my $RETURN_ON_ERR = Encode::RETURN_ON_ERR();
23             my $WARN_ON_ERR = Encode::WARN_ON_ERR();
24             my $XMLCREF = Encode::XMLCREF();
25              
26             # Workaround for encengine.c which cannot correctly map Unicode sequence
27             # with multiple characters.
28             my %composed = (
29             "\x{304B}\x{309A}" => "\x24\x77",
30             "\x{304D}\x{309A}" => "\x24\x78",
31             "\x{304F}\x{309A}" => "\x24\x79",
32             "\x{3051}\x{309A}" => "\x24\x7A",
33             "\x{3053}\x{309A}" => "\x24\x7B",
34             "\x{30AB}\x{309A}" => "\x25\x77",
35             "\x{30AD}\x{309A}" => "\x25\x78",
36             "\x{30AF}\x{309A}" => "\x25\x79",
37             "\x{30B1}\x{309A}" => "\x25\x7A",
38             "\x{30B3}\x{309A}" => "\x25\x7B",
39             "\x{30BB}\x{309A}" => "\x25\x7C",
40             "\x{30C4}\x{309A}" => "\x25\x7D",
41             "\x{30C8}\x{309A}" => "\x25\x7E",
42             "\x{31F7}\x{309A}" => "\x26\x78",
43             "\x{00E6}\x{0300}" => "\x2B\x44",
44             "\x{0254}\x{0300}" => "\x2B\x48",
45             "\x{0254}\x{0301}" => "\x2B\x49",
46             "\x{028C}\x{0300}" => "\x2B\x4A",
47             "\x{028C}\x{0301}" => "\x2B\x4B",
48             "\x{0259}\x{0300}" => "\x2B\x4C",
49             "\x{0259}\x{0301}" => "\x2B\x4D",
50             "\x{025A}\x{0300}" => "\x2B\x4E",
51             "\x{025A}\x{0301}" => "\x2B\x4F",
52             "\x{0301}" => "\x2B\x5A",
53             "\x{0300}" => "\x2B\x5C",
54             "\x{02E5}" => "\x2B\x60",
55             "\x{02E9}" => "\x2B\x64",
56             "\x{02E9}\x{02E5}" => "\x2B\x65",
57             "\x{02E5}\x{02E9}" => "\x2B\x66",
58             );
59             my $composed = join '|', reverse sort keys %composed;
60             my $composed_legacy = '[^\x00-\x1F\x7F-\x9F][\x{0300}-\x{036F}\x{309A}]+';
61             my $prohibited_ascii = '[\x21-\x7E]';
62             my $prohibited_jis = '[\x21-\x5B\x{00A5}\x5D-\x7D\x{203E}]';
63              
64             foreach my $encoding (
65             qw/jis-x-0208 jis-x-0208-0213 jis-x-0213-plane1 jis-x-0213-plane1-2000/
66             ) {
67             foreach my $alt ('', 'ascii', 'jis') {
68             my $name = $encoding . ($alt ? "-$alt" : "");
69             my $jisx0213 = ($name =~ /jis-x-0213/) ? 1 : 0;
70              
71             my $regexp;
72             unless ($jisx0213) {
73             if ($alt eq 'ascii') {
74             $regexp = qr{
75             \A (.*?) ($composed_legacy | $prohibited_ascii | \z)
76             }osx;
77             } elsif ($alt eq 'jis') {
78             $regexp = qr{
79             \A (.*?) ($composed_legacy | $prohibited_jis | \z)
80             }osx;
81             } else {
82             $regexp = qr{
83             \A (.*?) ($composed_legacy | \z)
84             }osx;
85             }
86             } else {
87             if ($alt eq 'ascii') {
88             $regexp = qr{\A (.*?) ($composed | $prohibited_ascii | \z)}osx;
89             } elsif ($alt eq 'jis') {
90             $regexp = qr{\A (.*?) ($composed | $prohibited_jis | \z)}osx;
91             } else {
92             $regexp = qr{\A (.*?) ($composed | \z)}osx;
93             }
94             }
95              
96             $Encode::Encoding{$name} = bless {
97             Name => $name,
98             alt => $alt,
99             encoding => $Encode::Encoding{"$encoding-canonic"},
100             jisx0213 => $jisx0213,
101             regexp => $regexp,
102             } => __PACKAGE__;
103             }
104             }
105              
106             # substitution cacharcter for multibyte.
107             my $subChar = "\x22\x2E"; # GETA MARK
108              
109             sub encode {
110 34972     34972 1 2629220 my ($self, $utf8, $chk) = @_;
111              
112 34972         29471 my $chk_sub;
113 34972 50       62848 if (ref $chk eq 'CODE') {
114 0         0 $chk_sub = $chk;
115 0         0 $chk = $LEAVE_SRC;
116             }
117 34972         37662 my $regexp = $self->{regexp};
118              
119 34972         31483 my $str = '';
120              
121             CHUNKS:
122 34972         90724 while ($utf8 =~ /./os) {
123 34972         32198 my $errChar = undef;
124              
125 34972         689365 while ($utf8 =~ s/$regexp//) {
126 50878         117697 my ($chunk, $mc) = ($1, $2);
127 50878 100 100     154911 last CHUNKS unless $chunk =~ /./os or $mc =~ /./os;
128              
129 35162 100       69010 if ($chunk =~ /./os) {
130 34684         130779 $str .= $self->{encoding}->encode($chunk, $FB_QUIET);
131 34684 100       75469 if ($chunk =~ /./os) {
132 19036         73982 $utf8 = $chunk . $mc . $utf8;
133 19036         23861 last;
134             }
135             }
136              
137 16126 100 66     26295 unless ($mc =~ /./os) {
    100          
138 15584         79234 next;
139             } elsif ($self->{jisx0213} and $composed{$mc}) {
140 322         476 $str .= $composed{$mc};
141 322         11179 next;
142             } else {
143 220         236 $errChar = $mc;
144 220         2831 $utf8 = $mc . $utf8;
145 220         402 last;
146             }
147             }
148              
149 19256 100       341056 $errChar = substr($utf8, 0, 1) unless defined $errChar;
150              
151 19256 50       31853 if ($chk & $DIE_ON_ERR) {
152 0         0 croak sprintf $err_encode_nomap, '}\x{', $errChar, $self->{Name};
153             }
154 19256 50       28572 if ($chk & $WARN_ON_ERR) {
155 0         0 carp sprintf $err_encode_nomap, '}\x{', $errChar, $self->{Name};
156             }
157 19256 50       27735 if ($chk & $RETURN_ON_ERR) {
158 19256         22241 last CHUNKS;
159             }
160              
161 0 0       0 if ($chk_sub) {
162 0         0 $str .= join '', map { $chk_sub->(ord $_) } split //, $errChar;
  0         0  
163             } else {
164 0         0 $str .= $subChar;
165             }
166 0         0 substr($utf8, 0, length $errChar) = '';
167             } # CHUNKS
168              
169 34972 50       72247 $_[1] = $utf8 unless $chk & $LEAVE_SRC;
170 34972         88575 return $str;
171             }
172              
173             sub decode {
174 3648     3648 1 753164 my ($self, $str, $chk) = @_;
175              
176 3648 50 33     18631 if ($self->{alt} and not ref $chk) {
177 3648         7085 $chk &= ~($PERLQQ | $XMLCREF | $HTMLCREF);
178             }
179 3648         35661 my $utf8 = $self->{encoding}->decode($str, $chk);
180 3648 50       7670 if ($self->{alt} eq 'ascii') {
    0          
181 3648         20009 $utf8 =~ s{($prohibited_ascii)}
182             {
183 940         2967 pack 'U', ord($1) + 0xFEE0;
184             }eg;
185             } elsif ($self->{alt} eq 'jis') {
186 0         0 $utf8 =~ s{($prohibited_jis)}
187             {
188 0         0 my $chr = ord $1;
189 0 0       0 if ($chr == 0x00A5) {
    0          
190 0         0 $chr = 0xFFE5;
191             } elsif ($chr == 0x203E) {
192 0         0 $chr = 0xFFE3;
193             } else {
194 0         0 $chr += 0xFEE0;
195             }
196 0         0 pack 'U', $chr;
197             }eg;
198             }
199              
200 3648 50 33     16499 $_[1] = $str unless ref $chk or $chk & $LEAVE_SRC;
201 3648         10502 return $utf8;
202             }
203              
204 0     0 1   sub perlio_ok { 0 }
205              
206             1;
207             __END__