/* $Id$ */ #include "Japanese.h" #include #ifndef __cplusplus #undef bool #undef true #undef false typedef enum bool { false, true, } bool; #endif #define DISP_U2S 0 #define DISP_S2U 0 #if DISP_U2S #define ECHO_U2S(arg) fprintf arg #define ON_U2S(cmd) cmd #else #define ECHO_U2S(arg) #define ON_U2S(cmd) #endif #if DISP_S2U #define ECHO_S2U(arg) fprintf arg #define ON_S2U(cmd) cmd #else #define ECHO_S2U(arg) #define ON_S2U(cmd) #endif /* ---------------------------------------------------------------------------- * SV* sv_utf8 = xs_sjis_imode2_utf8(SV* sv_sjis) * convert sjis(imode2) into utf8. * ------------------------------------------------------------------------- */ EXTERN_C SV* xs_sjis_imode2_utf8(SV* sv_str) { STRLEN src_len; UJ_UINT8* src; int len; SV_Buf result; const UJ_UINT8* src_end; if( sv_str==&PL_sv_undef ) { return newSVsv(&PL_sv_undef); } src = (UJ_UINT8*)SvPV(sv_str,src_len); len = sv_len(sv_str); #if DISP_S2U fprintf(stderr,"Unicode::Japanese::(xs)sjis_utf8_imode2\n",len); bin_dump("in ",src,len); #endif SV_Buf_init(&result,len*3/2+4); src_end = src+len; while( src imode2 * ------------------------------------------------------------------------- */ EXTERN_C SV* xs_utf8_sjis_imode2(SV* sv_str) { UJ_UINT8* src; int len; SV_Buf result; const UJ_UINT8* src_end; if( sv_str==&PL_sv_undef ) { return newSVsv(&PL_sv_undef); } src = (UJ_UINT8*)SvPV(sv_str,PL_na); len = sv_len(sv_str); ECHO_U2S((stderr,"Unicode::Japanese::(xs)utf8_sjis_imode1\n")); ON_U2S( bin_dump("in ",src,len) ); SV_Buf_init(&result,len+4); src_end = src+len; while( src U+10FFFF not supported by UTF-8 (RFC 3629). */ if( ucs>0x10FFFF ) { SV_Buf_append_ch(&result,'?'); continue; } }else if( 0xc0<=*src && *src<=0xdf ) { const int utf8_len = 2; const UJ_UINT32 ucs_min = 0x80; const UJ_UINT32 ucs_max = 0x7ff; ECHO_U2S((stderr,"utf8-len: [%d]\n",utf8_len)); /* check length */ if( src+utf8_len<=src_end ) { /* noop */ }else { /* no enough sequence */ SV_Buf_append_ch(&result,'?'); ++src; continue; } /* check follow sequences */ if( 0x80<=src[1] && src[1]<=0xbf ) { /* noop */ }else { SV_Buf_append_ch(&result,'?'); ++src; continue; } /* compute code point */ ucs = ((src[0] & 0x1F)<<6)|(src[1] & 0x3F); src += utf8_len; if( ucs_min<=ucs && ucs<=ucs_max ) { /* noop */ }else { /* illegal sequence */ SV_Buf_append_ch(&result,'?'); continue; } /* ok. */ }else if( 0xf8<=*src && *src<=0xfb ) { const int utf8_len = 5; ECHO_U2S((stderr,"utf8-len: [%d]\n",utf8_len)); /* check length */ if( src+utf8_len<=src_end ) { /* noop */ }else { /* no enough sequence */ SV_Buf_append_ch(&result,'?'); ++src; continue; } /* check follow sequences */ if( 0x80<=src[1] && src[1]<=0xbf && 0x80<=src[2] && src[2]<=0xbf && 0x80<=src[3] && src[3]<=0xbf && 0x80<=src[4] && src[4]<=0xbf ) { /* noop */ }else { SV_Buf_append_ch(&result,'?'); ++src; continue; } /* compute code point */ /* > U+10FFFF not supported by UTF-8 (RFC 3629). */ src += utf8_len; SV_Buf_append_ch(&result,'?'); continue; }else if( 0xfc<=*src && *src<=0xfd ) { const int utf8_len = 6; ECHO_U2S((stderr,"utf8-len: [%d]\n",utf8_len)); /* check length */ if( src+utf8_len<=src_end ) { /* noop */ }else { /* no enough sequence */ SV_Buf_append_ch(&result,'?'); ++src; continue; } /* check follow sequences */ if( 0x80<=src[1] && src[1]<=0xbf && 0x80<=src[2] && src[2]<=0xbf && 0x80<=src[3] && src[3]<=0xbf && 0x80<=src[4] && src[4]<=0xbf && 0x80<=src[5] && src[5]<=0xbf ) { /* noop */ }else { SV_Buf_append_ch(&result,'?'); ++src; continue; } /* compute code point */ /* > U+10FFFF not supported by UTF-8 (RFC 3629). */ src += utf8_len; SV_Buf_append_ch(&result,'?'); continue; }else { SV_Buf_append_ch(&result,'?'); ++src; continue; } /* ucs => sjis */ ECHO_U2S((stderr,"ucs [%04x]\n",ucs)); if( ucs<=0x9FFF ) { sjis_ptr = g_u2s_table + ucs*2; }else if( 0xF900<=ucs && ucs<=0xFFFF ) { sjis_ptr = g_u2s_table + (ucs - 0xF900 + 0xA000)*2; }else if( 0x0FE000<=ucs && ucs<=0x0FFFFF ) { sjis_ptr = (UJ_UINT8*)"?"; /* exactly 2byte: "?\0" */ }else { sjis_ptr = (UJ_UINT8*)"\0"; /* exactly 2byte: "\0\0" */ } if( sjis_ptr[0]!=0 || sjis_ptr[1]!=0 ) { /* mapping dest exists. */ if( sjis_ptr[1]!=0 ) { SV_Buf_append_mem(&result, sjis_ptr, 2); }else { SV_Buf_append_ch(&result,sjis_ptr[0]); } }else if( ucs<=0x7F ) { SV_Buf_append_ch(&result,(UJ_UINT8)ucs); }else { SV_Buf_append_ch(&result,'?'); } } /* while */ ON_U2S( bin_dump("out",SV_Buf_getBegin(&result),SV_Buf_getLength(&result)) ); SV_Buf_setLength(&result); return SV_Buf_getSv(&result); } /* ---------------------------------------------------------------------------- * End of File. * ------------------------------------------------------------------------- */