Created
May 1, 2024 21:41
-
-
Save mRB0/e3c15e2d88dc49ed1fa1ebb5bd5fd136 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// A simple wrapper. | |
// | |
// In Java: | |
// | |
// static String getString(String key); | |
// | |
// Calls the C++ function: | |
// | |
// C++: std::string openmpt::string::get(std::string &key); | |
// | |
// TODO: Might leak memory on exception throw. See within. | |
JNIEXPORT jstring JNICALL Java_com_mrb0_OpenMPT_getString | |
(JNIEnv *env, jclass, jstring keyJString) { | |
jstring charsetUtf8 = env->NewStringUTF("UTF-8"); | |
if (charsetUtf8 == NULL) { | |
return NULL; | |
} | |
jclass clsString = env->FindClass("java/lang/String"); | |
if (clsString == NULL) { | |
return NULL; | |
} | |
jmethodID getBytes = env->GetMethodID(clsString, "getBytes", "(Ljava/lang/String;)[B"); | |
if (getBytes == NULL) { | |
return NULL; | |
} | |
jbyteArray keyStringBytesJArray = (jbyteArray)env->CallObjectMethod(keyJString, getBytes, charsetUtf8); | |
if (env->ExceptionOccurred()) { | |
return NULL; | |
} | |
jsize keyStringBytesLength = env->GetArrayLength(keyStringBytesJArray); | |
if (env->ExceptionOccurred()) { | |
return NULL; | |
} | |
jbyte *keyStringBytesArray = env->GetByteArrayElements(keyStringBytesJArray, NULL); | |
if (keyStringBytesArray == NULL) { | |
return NULL; | |
} | |
std::string keyStdString((char *)keyStringBytesArray, keyStringBytesLength); | |
// TODO: Call this even if an exception is thrown after GetByteArrayElements. | |
env->ReleaseByteArrayElements(keyStringBytesJArray, keyStringBytesArray, JNI_ABORT); | |
if (env->ExceptionOccurred()) { | |
return NULL; | |
} | |
std::string value = openmpt::string::get(keyStdString); | |
jbyteArray valueBytesJArray = (jbyteArray)env->NewByteArray(value.size()); | |
if (valueBytesJArray == NULL) { | |
return NULL; | |
} | |
jbyte *valueBytesArray = env->GetByteArrayElements(valueBytesJArray, NULL); | |
if (valueBytesArray == NULL) { | |
return NULL; | |
} | |
jbyte *nextArrayPos = valueBytesArray; | |
for (char &c : value) { | |
*(nextArrayPos++) = c; | |
} | |
// TODO: Call this even if an exception is thrown after GetByteArrayElements. | |
env->ReleaseByteArrayElements(valueBytesJArray, valueBytesArray, 0); | |
if (env->ExceptionOccurred()) { | |
return NULL; | |
} | |
jmethodID newStringBytesCharset = env->GetMethodID(clsString, "<init>", "([BLjava/lang/String;)V"); | |
if (newStringBytesCharset == NULL) { | |
return NULL; | |
} | |
return (jstring)env->NewObject(clsString, newStringBytesCharset, valueBytesJArray, charsetUtf8); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment