Merge pull request #6089 from JosJuice/android-convert-str
android: Improve string conversion
This commit is contained in:
commit
a51b1cd3cd
8 changed files with 70 additions and 39 deletions
|
@ -1,4 +1,6 @@
|
||||||
add_library(citra-android SHARED
|
add_library(citra-android SHARED
|
||||||
|
android_common/android_common.cpp
|
||||||
|
android_common/android_common.h
|
||||||
applets/mii_selector.cpp
|
applets/mii_selector.cpp
|
||||||
applets/mii_selector.h
|
applets/mii_selector.h
|
||||||
applets/swkbd.cpp
|
applets/swkbd.cpp
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright 2022 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "jni/android_common/android_common.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
#include "common/string_util.h"
|
||||||
|
|
||||||
|
std::string GetJString(JNIEnv* env, jstring jstr) {
|
||||||
|
if (!jstr) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const jchar* jchars = env->GetStringChars(jstr, nullptr);
|
||||||
|
const jsize length = env->GetStringLength(jstr);
|
||||||
|
const std::u16string_view string_view(reinterpret_cast<const char16_t*>(jchars), length);
|
||||||
|
const std::string converted_string = Common::UTF16ToUTF8(string_view);
|
||||||
|
env->ReleaseStringChars(jstr, jchars);
|
||||||
|
|
||||||
|
return converted_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
jstring ToJString(JNIEnv* env, std::string_view str) {
|
||||||
|
const std::u16string converted_string = Common::UTF8ToUTF16(str);
|
||||||
|
return env->NewString(reinterpret_cast<const jchar*>(converted_string.data()),
|
||||||
|
static_cast<jint>(converted_string.size()));
|
||||||
|
}
|
12
src/android/app/src/main/jni/android_common/android_common.h
Normal file
12
src/android/app/src/main/jni/android_common/android_common.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
// Copyright 2022 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
std::string GetJString(JNIEnv* env, jstring jstr);
|
||||||
|
jstring ToJString(JNIEnv* env, std::string_view str);
|
|
@ -3,6 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
#include "jni/android_common/android_common.h"
|
||||||
#include "jni/applets/mii_selector.h"
|
#include "jni/applets/mii_selector.h"
|
||||||
#include "jni/id_cache.h"
|
#include "jni/id_cache.h"
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ void AndroidMiiSelector::Setup(const Frontend::MiiSelectorConfig& config) {
|
||||||
static_cast<jboolean>(config.enable_cancel_button));
|
static_cast<jboolean>(config.enable_cancel_button));
|
||||||
env->SetObjectField(java_config,
|
env->SetObjectField(java_config,
|
||||||
env->GetFieldID(s_mii_selector_config_class, "title", "Ljava/lang/String;"),
|
env->GetFieldID(s_mii_selector_config_class, "title", "Ljava/lang/String;"),
|
||||||
env->NewStringUTF(config.title.c_str()));
|
ToJString(env, config.title));
|
||||||
env->SetLongField(
|
env->SetLongField(
|
||||||
java_config,
|
java_config,
|
||||||
env->GetFieldID(s_mii_selector_config_class, "initially_selected_mii_index", "J"),
|
env->GetFieldID(s_mii_selector_config_class, "initially_selected_mii_index", "J"),
|
||||||
|
@ -39,7 +40,7 @@ void AndroidMiiSelector::Setup(const Frontend::MiiSelectorConfig& config) {
|
||||||
env->NewObjectArray(static_cast<jsize>(miis.size()), string_class, nullptr);
|
env->NewObjectArray(static_cast<jsize>(miis.size()), string_class, nullptr);
|
||||||
for (std::size_t i = 0; i < miis.size(); ++i) {
|
for (std::size_t i = 0; i < miis.size(); ++i) {
|
||||||
const auto name = Common::UTF16BufferToUTF8(miis[i].mii_name);
|
const auto name = Common::UTF16BufferToUTF8(miis[i].mii_name);
|
||||||
env->SetObjectArrayElement(array, static_cast<jsize>(i), env->NewStringUTF(name.c_str()));
|
env->SetObjectArrayElement(array, static_cast<jsize>(i), ToJString(env, name));
|
||||||
}
|
}
|
||||||
env->SetObjectField(
|
env->SetObjectField(
|
||||||
java_config,
|
java_config,
|
||||||
|
|
|
@ -3,22 +3,14 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
#include "jni/android_common/android_common.h"
|
||||||
#include "jni/applets/swkbd.h"
|
#include "jni/applets/swkbd.h"
|
||||||
#include "jni/id_cache.h"
|
#include "jni/id_cache.h"
|
||||||
|
|
||||||
static std::string GetJString(JNIEnv* env, jstring jstr) {
|
|
||||||
if (!jstr) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* s = env->GetStringUTFChars(jstr, nullptr);
|
|
||||||
std::string result = s;
|
|
||||||
env->ReleaseStringUTFChars(jstr, s);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static jclass s_software_keyboard_class;
|
static jclass s_software_keyboard_class;
|
||||||
static jclass s_keyboard_config_class;
|
static jclass s_keyboard_config_class;
|
||||||
static jclass s_keyboard_data_class;
|
static jclass s_keyboard_data_class;
|
||||||
|
@ -39,15 +31,15 @@ static jobject ToJavaKeyboardConfig(const Frontend::KeyboardConfig& config) {
|
||||||
static_cast<jboolean>(config.multiline_mode));
|
static_cast<jboolean>(config.multiline_mode));
|
||||||
env->SetObjectField(object,
|
env->SetObjectField(object,
|
||||||
env->GetFieldID(s_keyboard_config_class, "hint_text", "Ljava/lang/String;"),
|
env->GetFieldID(s_keyboard_config_class, "hint_text", "Ljava/lang/String;"),
|
||||||
env->NewStringUTF(config.hint_text.c_str()));
|
ToJString(env, config.hint_text));
|
||||||
|
|
||||||
const jclass string_class = reinterpret_cast<jclass>(env->FindClass("java/lang/String"));
|
const jclass string_class = reinterpret_cast<jclass>(env->FindClass("java/lang/String"));
|
||||||
const jobjectArray array =
|
const jobjectArray array =
|
||||||
env->NewObjectArray(static_cast<jsize>(config.button_text.size()), string_class,
|
env->NewObjectArray(static_cast<jsize>(config.button_text.size()), string_class,
|
||||||
env->NewStringUTF(config.button_text[0].c_str()));
|
ToJString(env, config.button_text[0]));
|
||||||
for (std::size_t i = 1; i < config.button_text.size(); ++i) {
|
for (std::size_t i = 1; i < config.button_text.size(); ++i) {
|
||||||
env->SetObjectArrayElement(array, static_cast<jsize>(i),
|
env->SetObjectArrayElement(array, static_cast<jsize>(i),
|
||||||
env->NewStringUTF(config.button_text[i].c_str()));
|
ToJString(env, config.button_text[i]));
|
||||||
}
|
}
|
||||||
env->SetObjectField(
|
env->SetObjectField(
|
||||||
object, env->GetFieldID(s_keyboard_config_class, "button_text", "[Ljava/lang/String;"),
|
object, env->GetFieldID(s_keyboard_config_class, "button_text", "[Ljava/lang/String;"),
|
||||||
|
@ -78,8 +70,7 @@ void AndroidKeyboard::Execute(const Frontend::KeyboardConfig& config) {
|
||||||
|
|
||||||
void AndroidKeyboard::ShowError(const std::string& error) {
|
void AndroidKeyboard::ShowError(const std::string& error) {
|
||||||
JNIEnv* env = IDCache::GetEnvForThread();
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
env->CallStaticVoidMethod(s_software_keyboard_class, s_swkbd_show_error,
|
env->CallStaticVoidMethod(s_software_keyboard_class, s_swkbd_show_error, ToJString(env, error));
|
||||||
env->NewStringUTF(error.c_str()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitJNI(JNIEnv* env) {
|
void InitJNI(JNIEnv* env) {
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "core/hle/service/nfc/nfc.h"
|
#include "core/hle/service/nfc/nfc.h"
|
||||||
#include "core/savestate.h"
|
#include "core/savestate.h"
|
||||||
#include "core/settings.h"
|
#include "core/settings.h"
|
||||||
|
#include "jni/android_common/android_common.h"
|
||||||
#include "jni/applets/mii_selector.h"
|
#include "jni/applets/mii_selector.h"
|
||||||
#include "jni/applets/swkbd.h"
|
#include "jni/applets/swkbd.h"
|
||||||
#include "jni/camera/ndk_camera.h"
|
#include "jni/camera/ndk_camera.h"
|
||||||
|
@ -58,24 +59,13 @@ std::condition_variable running_cv;
|
||||||
|
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
static std::string GetJString(JNIEnv* env, jstring jstr) {
|
|
||||||
if (!jstr) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* s = env->GetStringUTFChars(jstr, nullptr);
|
|
||||||
std::string result = s;
|
|
||||||
env->ReleaseStringUTFChars(jstr, s);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool DisplayAlertMessage(const char* caption, const char* text, bool yes_no) {
|
static bool DisplayAlertMessage(const char* caption, const char* text, bool yes_no) {
|
||||||
JNIEnv* env = IDCache::GetEnvForThread();
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
|
|
||||||
// Execute the Java method.
|
// Execute the Java method.
|
||||||
jboolean result = env->CallStaticBooleanMethod(
|
jboolean result = env->CallStaticBooleanMethod(
|
||||||
IDCache::GetNativeLibraryClass(), IDCache::GetDisplayAlertMsg(), env->NewStringUTF(caption),
|
IDCache::GetNativeLibraryClass(), IDCache::GetDisplayAlertMsg(), ToJString(env, caption),
|
||||||
env->NewStringUTF(text), yes_no ? JNI_TRUE : JNI_FALSE);
|
ToJString(env, text), yes_no ? JNI_TRUE : JNI_FALSE);
|
||||||
|
|
||||||
return result != JNI_FALSE;
|
return result != JNI_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -84,8 +74,8 @@ static std::string DisplayAlertPrompt(const char* caption, const char* text, int
|
||||||
JNIEnv* env = IDCache::GetEnvForThread();
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
|
|
||||||
jstring value = reinterpret_cast<jstring>(env->CallStaticObjectMethod(
|
jstring value = reinterpret_cast<jstring>(env->CallStaticObjectMethod(
|
||||||
IDCache::GetNativeLibraryClass(), IDCache::GetDisplayAlertPrompt(),
|
IDCache::GetNativeLibraryClass(), IDCache::GetDisplayAlertPrompt(), ToJString(env, caption),
|
||||||
env->NewStringUTF(caption), env->NewStringUTF(text), buttonConfig));
|
ToJString(env, text), buttonConfig));
|
||||||
|
|
||||||
return GetJString(env, value);
|
return GetJString(env, value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include "common/common_paths.h"
|
#include "common/common_paths.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
@ -135,14 +137,14 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string UTF16ToUTF8(const std::u16string& input) {
|
std::string UTF16ToUTF8(std::u16string_view input) {
|
||||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
|
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
|
||||||
return convert.to_bytes(input);
|
return convert.to_bytes(input.data(), input.data() + input.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::u16string UTF8ToUTF16(const std::string& input) {
|
std::u16string UTF8ToUTF16(std::string_view input) {
|
||||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
|
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
|
||||||
return convert.from_bytes(input);
|
return convert.from_bytes(input.data(), input.data() + input.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
|
@ -37,8 +38,8 @@ void BuildCompleteFilename(std::string& _CompleteFilename, const std::string& _P
|
||||||
[[nodiscard]] std::string ReplaceAll(std::string result, const std::string& src,
|
[[nodiscard]] std::string ReplaceAll(std::string result, const std::string& src,
|
||||||
const std::string& dest);
|
const std::string& dest);
|
||||||
|
|
||||||
[[nodiscard]] std::string UTF16ToUTF8(const std::u16string& input);
|
[[nodiscard]] std::string UTF16ToUTF8(std::u16string_view input);
|
||||||
[[nodiscard]] std::u16string UTF8ToUTF16(const std::string& input);
|
[[nodiscard]] std::u16string UTF8ToUTF16(std::string_view input);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
[[nodiscard]] std::string UTF16ToUTF8(const std::wstring& input);
|
[[nodiscard]] std::string UTF16ToUTF8(const std::wstring& input);
|
||||||
|
|
Loading…
Reference in a new issue