変換するロケールをjapanese以外にも出来るかな
昨日作ったJavaの文字化けを修正するプログラムですが、一方的にJapaneseしか扱っていなかったので、新しいLocaleをパラメータで渡すように変更しました。
また、クラスの名前もJapaneseだったのをCharSetに、メソッド名もFixCharsetをchangeLocaleに変更してみました。
先ずはJavaのクラスの方で
CharSet.java
package charset; public class CharSet { public CharSet() { } public static native String changeLocale(String Original, String newLocale); }
changeLocaleメソッドの第2パラメータに新しいロケールを指定できるようにしました。
次にCharSetクラスに対応したJNIプログラムの作成で、
これもCharSet.cppに名前を変更して、
#include <jni.h> #include "charset_CharSet.h" #include <locale> using std::locale; JNIEXPORT jstring JNICALL Java_charset_CharSet_changeLocale(JNIEnv *env, jclass cls, jstring original, jstring new_loc) { /* * Java文字列を一旦MBCS文字列に変換する */ wchar_t *words = (wchar_t *)env->GetStringChars(original, NULL); size_t mbs_len = wcstombs(NULL, words, wcslen(words)); char *mbs_value = (char *)calloc(mbs_len+1, sizeof(char)); mbs_len = wcstombs(mbs_value, words, wcslen(words)); env->ReleaseStringChars(original, (const jchar *)words); /* * Localeを取得する */ words = (wchar_t *)env->GetStringChars(new_loc, NULL); size_t loc_len = wcstombs(NULL, words, wcslen(words)); char *loc_value = (char *)calloc(loc_len+1, sizeof(char)); loc_len = wcstombs(loc_value, words, wcslen(words)); env->ReleaseStringChars(new_loc, (const jchar *)words); /* * MBCS文字列をLocal=new_locで再度Unicode文字列に変換し、結果をJava文字列に設定する */ locale new_locale(loc_value); locale old_locale = locale::global(new_locale); size_t wcs_len = mbstowcs(NULL, (const char *)mbs_value, mbs_len); wchar_t *wcs_value = (wchar_t *)calloc(wcs_len, sizeof(wchar_t)); wcs_len = mbstowcs(wcs_value, (const char *)mbs_value, mbs_len); jstring wcs_string = env->NewString((const jchar *)((wchar_t *)wcs_value), (jsize)wcs_len); locale::global(old_locale); free(mbs_value); free(loc_value); return wcs_string; }
としました。
変更点としては単純に追加された第2パラメータで設定された情報をlocale new_localeに渡すように変更しました。
ただこのプログラム自体は、japanese以外のロケールは試していませんので、あしからず。