File Coverage

eucjp.c
Criterion Covered Total %
statement 47 93 50.5
branch 38 130 29.2
condition n/a
subroutine n/a
pod n/a
total 85 223 38.1


line stmt bran cond sub pod time code
1              
2             #include "Japanese.h"
3             #include "sjis.h"
4              
5             #ifdef TEST
6             #define DISP_E2S 0
7             #define DISP_S2E 0
8             #endif
9              
10             /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
11             /* sjis=>eucjp変換 */
12             EXTERN_C
13             SV*
14 2           xs_sjis_eucjp(SV* sv_str)
15             {
16             unsigned char* src;
17             STRLEN len;
18             SV_Buf result;
19             const unsigned char* src_end;
20              
21 2 50         if( sv_str==&PL_sv_undef )
22             {
23 0           return newSVsv(&PL_sv_undef);
24             }
25 2 50         if( SvGMAGICAL(sv_str) )
26             {
27 0           mg_get(sv_str);
28             }
29 2 50         if( !SvOK(sv_str) )
30             {
31 0           return newSVsv(&PL_sv_undef);
32             }
33            
34 2           src = (unsigned char*)SvPV(sv_str, len);
35             /*fprintf(stderr,"Unicode::Japanese::(xs)sjis_eucjp\n",len); */
36             /*bin_dump("in ",src,len); */
37 2 50         if( len == 0 )
38             {
39 0           return newSVsv(&PL_sv_undef);
40             }
41 2 50         SV_Buf_init(&result,len);
    50          
42 2           src_end = src+len;
43              
44 4 100         while( src
45             {
46 2           switch(chk_sjis[*src])
47             {
48 1           case CHK_SJIS_THROUGH:
49 1           {
50 1           const unsigned char* start = src;
51 7 100         while( ++src
    50          
52 1 50         SV_Buf_append_mem(&result,start,src-start);
    50          
    50          
53 1           continue;
54             }
55 1           case CHK_SJIS_C:
56             {
57 1 50         if( src+2-1
    50          
    50          
    50          
58 1           {
59             union {
60             UJ_UINT16 u16_val;
61             UJ_UINT8 u8_val[2];
62             } tmp;
63 1 50         if( 0x9f <= src[1] )
64             {
65 1 50         tmp.u8_val[0] = src[0]*2 - (src[0]>=0xe0 ? 0xe0 : 0x60);
66 1           tmp.u8_val[1] = src[1] + 2;
67             }else
68             {
69 0 0         tmp.u8_val[0] = src[0]*2 - (src[0]>=0xe0 ? 0xe1 : 0x61);
70 0           tmp.u8_val[1] = src[1] + 0x60 + (src[1] < 0x7f);
71             }
72 1 50         SV_Buf_append_ch2(&result, tmp.u16_val);
    50          
    50          
73 1           src += 2;
74 1           continue;
75             }
76 0           break;
77             }
78 0           case CHK_SJIS_KANA:
79 0           {
80             union {
81             UJ_UINT16 u16_val;
82             UJ_UINT8 u8_val[2];
83             } tmp;
84 0           tmp.u8_val[0] = 0x8e;
85 0           tmp.u8_val[1] = src[0];
86 0 0         SV_Buf_append_ch2(&result, tmp.u16_val);
    0          
    0          
87 0           ++src;
88 0           continue;
89             }
90 0           default:
91             {
92             #ifdef TEST
93             fprintf(stderr,"xs_sjis_eucjp: invalid value [%02x] at chk_sjis[%05x]\n",chk_sjis[*src],*src);
94             #endif
95 0 0         SV_Buf_append_ch(&result,*src);
    0          
    0          
96 0           ++src;
97             }
98             } /*switch */
99              
100             /* invalid char */
101 0 0         SV_Buf_append_ch(&result,*src);
    0          
    0          
102 0           ++src;
103              
104             } /*while */
105              
106             /*bin_dump("out",result.getBegin(),result.getLength()); */
107 2           SV_Buf_setLength(&result);
108              
109 2           return SV_Buf_getSv(&result);
110             }
111              
112             /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
113             /* eucjp=>sjis変換文字判定 */
114             /* 1:EUCJP:0212, 3:EUCJP:C 4:EUCJP:KANA */
115             #define CHK_EUCJP_THROUGH 0
116             #define CHK_EUCJP_0212 1
117             #define CHK_EUCJP_C 3
118             #define CHK_EUCJP_KANA 4
119             static const unsigned char chk_eucjp[256] =
120             {
121             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */
122             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */
123             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */
124             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3 */
125             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4 */
126             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5 */
127             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6 */
128             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */
129             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, /* 8 */
130             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9 */
131             0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* a */
132             3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* b */
133             3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* c */
134             3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* d */
135             3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* e */
136             3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, /* f */
137             };
138              
139             /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
140             /* eucjp=>sjis変換 */
141             EXTERN_C
142             SV*
143 1           xs_eucjp_sjis(SV* sv_str)
144             {
145             unsigned char* src;
146             STRLEN len;
147             SV_Buf result;
148             const unsigned char* src_end;
149              
150 1 50         if( sv_str==&PL_sv_undef )
151             {
152 0           return newSVsv(&PL_sv_undef);
153             }
154 1 50         if( SvGMAGICAL(sv_str) )
155             {
156 0           mg_get(sv_str);
157             }
158 1 50         if( !SvOK(sv_str) )
159             {
160 0           return newSVsv(&PL_sv_undef);
161             }
162            
163 1           src = (unsigned char*)SvPV(sv_str, len);
164             #if DISP_E2S
165             fprintf(stderr,"Unicode::Japanese::(xs)eucjp_sjis\n",len);
166             bin_dump("in ",src,len);
167             #endif
168 1 50         SV_Buf_init(&result,len);
    50          
169 1           src_end = src+len;
170              
171 2 100         while( src
172             {
173 1           switch(chk_eucjp[*src])
174             {
175 0           case CHK_EUCJP_THROUGH:
176 0           {
177 0           const unsigned char* start = src;
178 0 0         while( ++src
    0          
179 0 0         SV_Buf_append_mem(&result,start,src-start);
    0          
    0          
180 0           continue;
181             }
182 0           case CHK_EUCJP_0212:
183             {
184 0 0         if( src+3-1
185             {
186 0 0         SV_Buf_append_mem(&result,UNDEF_SJIS,UNDEF_SJIS_LEN);
    0          
    0          
187 0           src += 3;
188 0           continue;
189             }
190 0           break;
191             }
192 1           case CHK_EUCJP_C:
193             {
194 1 50         if( src+2-1
    50          
    50          
195 1           {
196             union {
197             UJ_UINT16 u16_val;
198             UJ_UINT8 u8_val[2];
199             } tmp;
200 1 50         if( src[0]%2 )
201             {
202 0 0         tmp.u8_val[0] = (src[0]>>1) + (src[0] < 0xdf ? 0x31 : 0x71);
203 0 0         tmp.u8_val[1] = src[1] - ( 0x60 + (src[1] < 0xe0) );
204             }else
205             {
206 1 50         tmp.u8_val[0] = (src[0]>>1) + (src[0] < 0xdf ? 0x30 : 0x70);
207 1           tmp.u8_val[1] = src[1] - 2;
208             }
209 1 50         SV_Buf_append_ch2(&result, tmp.u16_val);
    50          
    50          
210 1           src += 2;
211 1           continue;
212             }
213 0           break;
214             }
215 0           case CHK_EUCJP_KANA:
216             {
217 0 0         if( src+2-1
    0          
    0          
218             {
219 0 0         SV_Buf_append_ch(&result,src[1]);
    0          
    0          
220 0           src += 2;
221 0           continue;
222             }
223 0           break;
224             }
225 0           default:
226             {
227             #ifdef TEST
228             fprintf(stderr,"xs_eucjp_sjis, invalid value [%02x] at chk_sjis[%05x]\n",chk_sjis[*src],*src);
229             #endif
230             }
231             } /*switch */
232              
233             /* invalid char */
234 0 0         SV_Buf_append_ch(&result,*src);
    0          
    0          
235 0           ++src;
236             } /*while */
237              
238             #if DISP_E2S
239             bin_dump("out",result.getBegin(),result.getLength());
240             #endif
241              
242 1           SV_Buf_setLength(&result);
243              
244 1           return SV_Buf_getSv(&result);
245             }