Merge pull request #6089 from JosJuice/android-convert-str

android: Improve string conversion
master
SachinVin 2022-08-04 13:47:49 +07:00 committed by GitHub
commit a51b1cd3cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 70 additions and 39 deletions

@ -1,4 +1,6 @@
add_library(citra-android SHARED
android_common/android_common.cpp
android_common/android_common.h
applets/mii_selector.cpp
applets/mii_selector.h
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()));
}

@ -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.
#include "common/string_util.h"
#include "jni/android_common/android_common.h"
#include "jni/applets/mii_selector.h"
#include "jni/id_cache.h"
@ -26,7 +27,7 @@ void AndroidMiiSelector::Setup(const Frontend::MiiSelectorConfig& config) {
static_cast<jboolean>(config.enable_cancel_button));
env->SetObjectField(java_config,
env->GetFieldID(s_mii_selector_config_class, "title", "Ljava/lang/String;"),
env->NewStringUTF(config.title.c_str()));
ToJString(env, config.title));
env->SetLongField(
java_config,
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);
for (std::size_t i = 0; i < miis.size(); ++i) {
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(
java_config,

@ -3,22 +3,14 @@
// Refer to the license.txt file included.
#include <map>
#include <jni.h>
#include "core/core.h"
#include "jni/android_common/android_common.h"
#include "jni/applets/swkbd.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_keyboard_config_class;
static jclass s_keyboard_data_class;
@ -39,15 +31,15 @@ static jobject ToJavaKeyboardConfig(const Frontend::KeyboardConfig& config) {
static_cast<jboolean>(config.multiline_mode));
env->SetObjectField(object,
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 jobjectArray array =
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) {
env->SetObjectArrayElement(array, static_cast<jsize>(i),
env->NewStringUTF(config.button_text[i].c_str()));
ToJString(env, config.button_text[i]));
}
env->SetObjectField(
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) {
JNIEnv* env = IDCache::GetEnvForThread();
env->CallStaticVoidMethod(s_software_keyboard_class, s_swkbd_show_error,
env->NewStringUTF(error.c_str()));
env->CallStaticVoidMethod(s_software_keyboard_class, s_swkbd_show_error, ToJString(env, error));
}
void InitJNI(JNIEnv* env) {

@ -27,6 +27,7 @@
#include "core/hle/service/nfc/nfc.h"
#include "core/savestate.h"
#include "core/settings.h"
#include "jni/android_common/android_common.h"
#include "jni/applets/mii_selector.h"
#include "jni/applets/swkbd.h"
#include "jni/camera/ndk_camera.h"
@ -58,24 +59,13 @@ std::condition_variable running_cv;
} // 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) {
JNIEnv* env = IDCache::GetEnvForThread();
// Execute the Java method.
jboolean result = env->CallStaticBooleanMethod(
IDCache::GetNativeLibraryClass(), IDCache::GetDisplayAlertMsg(), env->NewStringUTF(caption),
env->NewStringUTF(text), yes_no ? JNI_TRUE : JNI_FALSE);
IDCache::GetNativeLibraryClass(), IDCache::GetDisplayAlertMsg(), ToJString(env, caption),
ToJString(env, text), yes_no ? JNI_TRUE : 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();
jstring value = reinterpret_cast<jstring>(env->CallStaticObjectMethod(
IDCache::GetNativeLibraryClass(), IDCache::GetDisplayAlertPrompt(),
env->NewStringUTF(caption), env->NewStringUTF(text), buttonConfig));
IDCache::GetNativeLibraryClass(), IDCache::GetDisplayAlertPrompt(), ToJString(env, caption),
ToJString(env, text), buttonConfig));
return GetJString(env, value);
}

@ -8,6 +8,8 @@
#include <cstdlib>
#include <locale>
#include <sstream>
#include <string>
#include <string_view>
#include "common/common_paths.h"
#include "common/logging/log.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;
}
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;
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;
return convert.from_bytes(input);
return convert.from_bytes(input.data(), input.data() + input.size());
}
#ifdef _WIN32

@ -7,6 +7,7 @@
#include <algorithm>
#include <cstddef>
#include <string>
#include <string_view>
#include <vector>
#include "common/common_types.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,
const std::string& dest);
[[nodiscard]] std::string UTF16ToUTF8(const std::u16string& input);
[[nodiscard]] std::u16string UTF8ToUTF16(const std::string& input);
[[nodiscard]] std::string UTF16ToUTF8(std::u16string_view input);
[[nodiscard]] std::u16string UTF8ToUTF16(std::string_view input);
#ifdef _WIN32
[[nodiscard]] std::string UTF16ToUTF8(const std::wstring& input);