/* $Id: conv.c,v 1.4 2002/10/31 11:08:50 hio Exp $ */ #ifdef _MSC_VER #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include #include #define snprintf _snprintf #endif #include "Japanese.h" #include #ifndef _MSC_VER #include #endif #define DISP_S2U 0 #define DISP_U2S 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 #ifndef __cplusplus #undef bool #undef true #undef false typedef enum bool { false, true, } bool; #endif EXTERN_C SV* xs_sjis_utf8(SV* sv_str) { STRLEN src_len; unsigned char* src; int len; SV_Buf result; const unsigned char* src_end; if( sv_str==&PL_sv_undef ) { return newSVsv(&PL_sv_undef); } src = (unsigned char*)SvPV(sv_str,src_len); len = sv_len(sv_str); #if DISP_S2U fprintf(stderr,"Unicode::Japanese::(xs)sjis_utf8\n",len); bin_dump("in ",src,len); #endif SV_Buf_init(&result,len*3/2+4); src_end = src+len; while( src=src_end ) { ECHO_U2S((stderr," no enough buffer, here is %d, need %d\n",src_end-src,utf8_len)); SV_Buf_append_ch(&result,'?'); ++src; continue; } /* 2バイト目以降が正しい文字範囲か確認 */ succ = true; for( i=1; i=4); src += utf8_len; continue; } if( ucs & ~0xFFFF ) { /* ucs2の範囲外 (ucs4の範囲) */ SV_Buf_append_entityref(&result,ucs); src += utf8_len; continue; } /* ucs => sjis */ ECHO_U2S((stderr,"ucs2 [%04x]\n",ucs)); ECHO_U2S((stderr,"sjis [%04x]\n",ntohs(g_u2s_table[ucs]) )); if( g_u2s_table[ucs] || !ucs ) { /* 対応文字がある時とucs=='\0'の時 */ if( g_u2s_table[ucs] & 0xff00 ) { SV_Buf_append_ch2(&result,g_u2s_table[ucs]); }else { SV_Buf_append_ch(&result,(unsigned char)g_u2s_table[ucs]); } }else if( ucs<=0x7F ) { SV_Buf_append_ch(&result,(unsigned char)ucs); }else { SV_Buf_append_entityref(&result,ucs); } src += utf8_len; /*bin_dump("now",dst_begin,dst-dst_begin); */ } /* for */ ON_U2S( bin_dump("out",result.getBegin(),result.getLength()) ); SV_Buf_setLength(&result); return SV_Buf_getSv(&result); }