Index: ext/riconv.c =================================================================== --- ext/riconv.c +++ ext/riconv.c @@ -24,132 +24,98 @@ static const char* cs_ms932 = "MS932"; static const char* cs_utf8 = "UTF-8"; -/* Regexp::matchのラッパー */ +VALUE objIconvJ2R; +VALUE objIconvR2J; +char* charcode; + +/* wrap Regexp::match */ static int regxp_is_match(VALUE str, VALUE regxp) { return rb_funcall(str, rb_intern("match"), 1, RREGEXP(regxp)) != Qnil ? 1 : 0 ; } -/* RUBY_PLATFORMから類推してWindowsなら1を、そうでなければ0を返す */ +/* result true if windows */ static int platform_is_windows() { - VALUE platform = rb_const_get(rb_cObject, rb_intern("RUBY_PLATFORM")); + VALUE platform = rb_const_get(rb_cObject, rb_intern("RUBY_PLATFORM")); return regxp_is_match(platform, rb_str_new2("msvcrt|mswin|bccwin|mingw|cygwin")) - ? 1 - : 0; + ? 1 + : 0; } /* - * RUBY_PLATFORMと$KCODEを元にIconvで有効な適当な文字コード名を返す - * TODO: 実行環境のLOCALE,LANG,LC_ALL等も参考にする + * Get better charcode name */ -static char* get_charset_name() +static char* get_charcode_name() { char* result = NULL; - ID id_Iconv = rb_intern("Iconv"); - - if (rb_const_defined(rb_cObject, id_Iconv)) - { - VALUE kcode = rb_gv_get("$KCODE"); - VALUE platform = rb_const_get(rb_cObject, rb_intern("RUBY_PLATFORM")); - char* kcodep = (TYPE(kcode) == T_STRING) ? StringValuePtr(kcode) : ""; - switch(toupper(*kcodep)) - { - case 'E': - result = (char*)cs_eucjp; - break; - case 'S': - if (platform_is_windows()) - { - result = (char*)cs_cp932; - } - else - { - result = (char*)cs_sjis; - } - break; - case 'N': - if (platform_is_windows()) - { - result = (char*)cs_cp932; - } - else - { - result = NULL; - } - break; - case 'U': - default: - result = NULL; - break; - } - }else{ - result = NULL; - } + VALUE kcode = rb_gv_get("$KCODE"); + char* kcodep = (TYPE(kcode) == T_STRING) ? StringValuePtr(kcode) : ""; + + switch(toupper(*kcodep)) + { + case 'E': + result = (char*)cs_eucjp; + break; + case 'S': + if (platform_is_windows()) + { + result = (char*)cs_cp932; + } + else + { + result = (char*)cs_sjis; + } + break; + case 'N': + if (platform_is_windows()) + { + //for ruby1.8. YARV support better m17n. + result = (char*)cs_cp932; + } + else + { + result = (char*)cs_utf8; + } + break; + case 'U': + default: + result = (char*)cs_utf8; + break; + } return result; } -/* - * 拡張ライブラリのIconvがある場合は1,ない場合は0を返す - */ -static int has_exticonv() -{ - ID id_Iconv = rb_intern("Iconv"); - VALUE Iconv = rb_const_get(rb_cObject, id_Iconv); - if(Iconv == Qnil) - { - return 0; - } - else - { - return 1; - } -} - VALUE exticonv_local_to_utf8(VALUE local_string) { - char* cs = get_charset_name(); - if(cs) - { - return exticonv_cc(local_string, cs, cs_utf8); - } - else - { - return local_string; - } + if(charcode && charcode[0] != 'U') + { + return rb_ary_entry(rb_funcall(objIconvR2J, rb_intern("iconv"), 1, local_string), 0); + } + else + { + return local_string; + } } VALUE exticonv_utf8_to_local(VALUE utf8_string) { - char* cs = get_charset_name(); - if(cs) - { - return exticonv_cc(utf8_string, cs_utf8, cs); - } - else - { - return utf8_string; - } + if(charcode && charcode[0] != 'U') + { + return rb_ary_entry(rb_funcall(objIconvJ2R, rb_intern("iconv"), 1, utf8_string), 0); + } + else + { + return utf8_string; + } } -VALUE exticonv_cc(VALUE original_string, const char* from, const char* to) +void exticonv_init() { - return exticonv_vv(original_string, rb_str_new2(from), rb_str_new2(to)); + VALUE rb_iconv_klass = rb_const_get(rb_cObject, rb_intern("Iconv")); + ID sym_new = rb_intern("new"); + charcode = get_charcode_name(); + objIconvJ2R = rb_funcall(rb_iconv_klass, sym_new, 2, rb_str_new2(cs_utf8), rb_str_new2(charcode)); + objIconvR2J = rb_funcall(rb_iconv_klass, sym_new, 2, rb_str_new2(charcode), rb_str_new2(cs_utf8)); } - -VALUE exticonv_vv(VALUE original_string, VALUE from, VALUE to) -{ - if(has_exticonv()) - { - ID id_Iconv = rb_intern("Iconv"); - ID id_iconv = rb_intern("iconv"); - VALUE Iconv = rb_const_get(rb_cObject, id_Iconv); - return rb_ary_entry(rb_funcall(Iconv, id_iconv, 3, to, from, original_string), 0); - } - else - { - //iconvがなければそのまま返す - return original_string; - } -} Index: ext/riconv.h =================================================================== --- ext/riconv.h +++ ext/riconv.h @@ -19,7 +19,6 @@ extern VALUE exticonv_local_to_utf8(VALUE); extern VALUE exticonv_utf8_to_local(VALUE); -extern VALUE exticonv_cc(VALUE, const char*, const char*); -extern VALUE exticonv_vv(VALUE, VALUE, VALUE); +extern void exticonv_init(); #endif /* _RICONV_H */ Index: ext/rjb.c =================================================================== --- ext/rjb.c +++ ext/rjb.c @@ -2692,6 +2692,7 @@ void Init_rjbcore() { rb_protect((VALUE(*)(VALUE))rb_require, (VALUE)"iconv", NULL); + exticonv_init(); rjb_loaded_classes = rb_hash_new(); OBJ_FREEZE(rjb_loaded_classes);