Changed method for converting between java and c strings, to convert using an intermediate wchar_t string. Should be more reliable than trying to probe the character encoding.
This commit is contained in:
@@ -23,10 +23,8 @@
|
|||||||
#include "generic.h"
|
#include "generic.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <locale.h>
|
|
||||||
#include <xlocale.h>
|
|
||||||
#include <langinfo.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
void mark_failed_with_errno(JNIEnv *env, const char* message, jobject result) {
|
void mark_failed_with_errno(JNIEnv *env, const char* message, jobject result) {
|
||||||
const char * errno_message = NULL;
|
const char * errno_message = NULL;
|
||||||
@@ -40,47 +38,46 @@ void mark_failed_with_errno(JNIEnv *env, const char* message, jobject result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
char* java_to_char(JNIEnv *env, jstring string, jobject result) {
|
char* java_to_char(JNIEnv *env, jstring string, jobject result) {
|
||||||
// TODO - share this code with nnn_getSystemInfo() below
|
size_t stringLen = env->GetStringLength(string);
|
||||||
// Empty string means load locale from environment.
|
wchar_t* wideString = (wchar_t*)malloc(sizeof(wchar_t) * (stringLen+1));
|
||||||
locale_t locale = newlocale(LC_CTYPE_MASK, "", NULL);
|
const jchar* javaString = env->GetStringChars(string, NULL);
|
||||||
if (locale == NULL) {
|
for (size_t i = 0; i < stringLen; i++) {
|
||||||
mark_failed_with_message(env, "could not create locale", result);
|
wideString[i] = javaString[i];
|
||||||
|
}
|
||||||
|
wideString[stringLen] = L'\0';
|
||||||
|
env->ReleaseStringChars(string, javaString);
|
||||||
|
|
||||||
|
size_t bytes = wcstombs(NULL, wideString, 0);
|
||||||
|
if (bytes < 0) {
|
||||||
|
mark_failed_with_message(env, "could not convert string to current locale", result);
|
||||||
|
free(wideString);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
jstring encoding = env->NewStringUTF(nl_langinfo_l(CODESET, locale));
|
char* chars = (char*)malloc(bytes + 1);
|
||||||
freelocale(locale);
|
wcstombs(chars, wideString, bytes+1);
|
||||||
|
free(wideString);
|
||||||
jclass strClass = env->FindClass("java/lang/String");
|
|
||||||
jmethodID method = env->GetMethodID(strClass, "getBytes", "(Ljava/lang/String;)[B");
|
|
||||||
jbyteArray byteArray = (jbyteArray)env->CallObjectMethod(string, method, encoding);
|
|
||||||
size_t len = env->GetArrayLength(byteArray);
|
|
||||||
char* chars = (char*)malloc(len + 1);
|
|
||||||
env->GetByteArrayRegion(byteArray, 0, len, (jbyte*)chars);
|
|
||||||
chars[len] = 0;
|
|
||||||
|
|
||||||
return chars;
|
return chars;
|
||||||
}
|
}
|
||||||
|
|
||||||
jstring char_to_java(JNIEnv* env, const char* chars, jobject result) {
|
jstring char_to_java(JNIEnv* env, const char* chars, jobject result) {
|
||||||
// TODO - share this code with nnn_getSystemInfo() below
|
size_t bytes = strlen(chars);
|
||||||
// Empty string means load locale from environment.
|
wchar_t* wideString = (wchar_t*)malloc(sizeof(wchar_t) * (bytes+1));
|
||||||
locale_t locale = newlocale(LC_CTYPE_MASK, "", NULL);
|
if (mbstowcs(wideString, chars, bytes+1) < 0) {
|
||||||
if (locale == NULL) {
|
mark_failed_with_message(env, "could not convert string from current locale", result);
|
||||||
mark_failed_with_message(env, "could not create locale", result);
|
free(wideString);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
jstring encoding = env->NewStringUTF(nl_langinfo_l(CODESET, locale));
|
size_t stringLen = wcslen(wideString);
|
||||||
freelocale(locale);
|
jchar* javaString = (jchar*)malloc(sizeof(jchar) * stringLen);
|
||||||
|
for (int i =0; i < stringLen; i++) {
|
||||||
size_t len = strlen(chars);
|
javaString[i] = (jchar)wideString[i];
|
||||||
jbyteArray byteArray = env->NewByteArray(len);
|
}
|
||||||
jbyte* bytes = env->GetByteArrayElements(byteArray, NULL);
|
jstring string = env->NewString(javaString, stringLen);
|
||||||
memcpy(bytes, chars, len);
|
free(wideString);
|
||||||
env->ReleaseByteArrayElements(byteArray, bytes, JNI_COMMIT);
|
free(javaString);
|
||||||
jclass strClass = env->FindClass("java/lang/String");
|
return string;
|
||||||
jmethodID method = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
|
|
||||||
return (jstring)env->NewObject(strClass, method, byteArray, encoding);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user