| /* | |
| * This Source Code Form is subject to the terms of the Mozilla Public | |
| * License, v. 2.0. If a copy of the MPL was not distributed with this | |
| * file, You can obtain one at https://mozilla.org/MPL/2.0/. | |
| * | |
| * Copyright 2022 Michael Whapples | |
| */ | |
| use jni::objects::{JObject, JString, JValue}; | |
| use jni::sys::{jboolean, jint, jobject, jstring, JNI_TRUE}; | |
| use jni::JNIEnv; | |
| use libmathcat::errors::Error; | |
| use libmathcat::*; | |
| use std::panic::{self, AssertUnwindSafe}; | |
| #[unsafe(no_mangle)] | |
| pub extern "system" fn Java_onl_mdw_mathcat4j_api_MathCatJni_getVersion( | |
| mut env: JNIEnv, | |
| _obj: JObject, | |
| ) -> jstring { | |
| let result = panic::catch_unwind(AssertUnwindSafe(|| { | |
| env.new_string(get_version()).expect("Could not create6 java string").into_raw() | |
| })); | |
| match result { | |
| Ok(s) => s, | |
| Err(_) => { | |
| let _ = env.throw_new("onl/mdw/mathcat4j/api/PanicException", "Panic in MathCAT"); | |
| JObject::null().into_raw() | |
| } | |
| } | |
| } | |
| #[unsafe(no_mangle)] | |
| pub extern "system" fn Java_onl_mdw_mathcat4j_api_MathCatJni_setRulesDir( | |
| mut env: JNIEnv, | |
| _obj: JObject, | |
| dir: JString, | |
| ) { | |
| let result = panic::catch_unwind(AssertUnwindSafe(|| { | |
| let dir = env.get_string(&dir).expect("Could not get string value of dir").into(); | |
| let _ = set_rules_dir(dir) | |
| .or_else(|e| env.throw_new("java/lang/RuntimeException", errors_to_string(&e))); | |
| JObject::null().into_raw() | |
| })); | |
| match result { | |
| Ok(s) => s, | |
| Err(_) => { | |
| let _ = env.throw_new("onl/mdw/mathcat4j/api/PanicException", "Panic in MathCAT"); | |
| JObject::null().into_raw() | |
| } | |
| }; | |
| } | |
| #[unsafe(no_mangle)] | |
| pub extern "system" fn Java_onl_mdw_mathcat4j_api_MathCatJni_addFileString( | |
| mut env: JNIEnv, | |
| _obj: JObject, | |
| path: JString, | |
| content: JString, | |
| ) { | |
| let result = panic::catch_unwind(AssertUnwindSafe(|| { | |
| let path: String = env.get_string(&path).expect("Could not get string for path").into(); | |
| let content: String = env.get_string(&content).expect("Could not get string for content").into(); | |
| libmathcat::shim_filesystem::add_in_memory_file(&path, &content); | |
| JObject::null().into_raw() | |
| })); | |
| match result { | |
| Ok(s) => s, | |
| Err(_) => { | |
| let _ = env.throw_new("onl/mdw/mathcat4j/api/PanicException", "Panic in MathCAT"); | |
| JObject::null().into_raw() | |
| } | |
| }; | |
| } | |
| #[unsafe(no_mangle)] | |
| pub extern "system" fn Java_onl_mdw_mathcat4j_api_MathCatJni_setPreference( | |
| mut env: JNIEnv, | |
| _obj: JObject, | |
| name: JString, | |
| value: JString, | |
| ) { | |
| let result = panic::catch_unwind(AssertUnwindSafe(|| { | |
| let name = env.get_string(&name).expect("Could not get string for name").into(); | |
| let value = env.get_string(&value).expect("Could not get string for value").into(); | |
| let _ = set_preference(name, value) | |
| .or_else(|e| env.throw_new("java/lang/RuntimeException", errors_to_string(&e))); | |
| JObject::null().into_raw() | |
| })); | |
| match result { | |
| Ok(s) => s, | |
| Err(_) => { | |
| let _ = env.throw_new("onl/mdw/mathcat4j/api/PanicException", "Panic in MathCAT"); | |
| JObject::null().into_raw() | |
| } | |
| }; | |
| } | |
| #[unsafe(no_mangle)] | |
| pub extern "system" fn Java_onl_mdw_mathcat4j_api_MathCatJni_getPreference( | |
| mut env: JNIEnv, | |
| _obj: JObject, | |
| name: JString, | |
| ) -> jstring { | |
| let result = panic::catch_unwind(AssertUnwindSafe(|| { | |
| let name = env.get_string(&name).expect("Could not get string for name").into(); | |
| let result = get_preference(name); | |
| get_string_or_throw(&mut env, result) | |
| })); | |
| match result { | |
| Ok(s) => s, | |
| Err(_) => { | |
| let _ = env.throw_new("onl/mdw/mathcat4j/api/PanicException", "Panic in MathCAT"); | |
| JObject::null().into_raw() | |
| } | |
| } | |
| } | |
| #[unsafe(no_mangle)] | |
| pub extern "system" fn Java_onl_mdw_mathcat4j_api_MathCatJni_setMathml( | |
| mut env: JNIEnv, | |
| _obj: JObject, | |
| mathml_str: JString, | |
| ) -> jstring { | |
| let result = panic::catch_unwind(AssertUnwindSafe(|| { | |
| let mathml_str = | |
| env.get_string(&mathml_str).expect("Could not get string value of mathml_str").into(); | |
| let canonical_mathml_result = set_mathml(mathml_str); | |
| get_string_or_throw(&mut env, canonical_mathml_result) | |
| })); | |
| match result { | |
| Ok(s) => s, | |
| Err(_) => { | |
| let _ = env.throw_new("onl/mdw/mathcat4j/api/PanicException", "Panic in MathCAT"); | |
| JObject::null().into_raw() | |
| } | |
| } | |
| } | |
| #[unsafe(no_mangle)] | |
| pub extern "system" fn Java_onl_mdw_mathcat4j_api_MathCatJni_getBraille( | |
| mut env: JNIEnv, | |
| _obj: JObject, | |
| navigation_id: JString, | |
| ) -> jstring { | |
| let result = panic::catch_unwind(AssertUnwindSafe(|| { | |
| let navigation_id = env | |
| .get_string(&navigation_id) | |
| .expect("Could not get Java String for navigation_id") | |
| .into(); | |
| let braille_result = get_braille(navigation_id); | |
| get_string_or_throw(&mut env, braille_result) | |
| })); | |
| match result { | |
| Ok(s) => s, | |
| Err(_) => { | |
| let _ = env.throw_new("onl/mdw/mathcat4j/api/PanicException", "Panic in MathCAT"); | |
| JObject::null().into_raw() | |
| } | |
| } | |
| } | |
| #[unsafe(no_mangle)] | |
| pub extern "system" fn Java_onl_mdw_mathcat4j_api_MathCatJni_getSpokenText( | |
| mut env: JNIEnv, | |
| _obj: JObject, | |
| ) -> jstring { | |
| let result = panic::catch_unwind(AssertUnwindSafe(|| { | |
| let spoken_result = get_spoken_text(); | |
| get_string_or_throw(&mut env, spoken_result) | |
| })); | |
| match result { | |
| Ok(s) => s, | |
| Err(_) => { | |
| let _ = env.throw_new("onl/mdw/mathcat4j/api/PanicException", "Panic in MathCAT"); | |
| JObject::null().into_raw() | |
| } | |
| } | |
| } | |
| #[unsafe(no_mangle)] | |
| pub extern "system" fn Java_onl_mdw_mathcat4j_api_MathCatJni_getOverviewText( | |
| mut env: JNIEnv, | |
| _obj: JObject, | |
| ) -> jstring { | |
| let result = panic::catch_unwind(AssertUnwindSafe(|| { | |
| let overview_result = get_overview_text(); | |
| get_string_or_throw(&mut env, overview_result) | |
| })); | |
| match result { | |
| Ok(s) => s, | |
| Err(_) => { | |
| let _ = env.throw_new("onl/mdw/mathcat4j/api/PanicException", "Panic in MathCAT"); | |
| JObject::null().into_raw() | |
| } | |
| } | |
| } | |
| #[unsafe(no_mangle)] | |
| pub extern "system" fn Java_onl_mdw_mathcat4j_api_MathCatJni_doNavigateKeypress( | |
| mut env: JNIEnv, | |
| _obj: JObject, | |
| key: jint, | |
| shift_key: jboolean, | |
| control_key: jboolean, | |
| alt_key: jboolean, | |
| meta_key: jboolean, | |
| ) -> jstring { | |
| let result = panic::catch_unwind(AssertUnwindSafe(|| { | |
| let result = do_navigate_keypress( | |
| key as usize, | |
| shift_key == JNI_TRUE, | |
| control_key == JNI_TRUE, | |
| alt_key == JNI_TRUE, | |
| meta_key == JNI_TRUE, | |
| ); | |
| get_string_or_throw(&mut env, result) | |
| })); | |
| match result { | |
| Ok(s) => s, | |
| Err(_) => { | |
| let _ = env.throw_new("onl/mdw/mathcat4j/api/PanicException", "Panic in MathCAT"); | |
| JObject::null().into_raw() | |
| } | |
| } | |
| } | |
| #[unsafe(no_mangle)] | |
| pub extern "system" fn Java_onl_mdw_mathcat4j_api_MathCatJni_doNavigateCommand( | |
| mut env: JNIEnv, | |
| _obj: JObject, | |
| command: JString, | |
| ) -> jstring { | |
| let result = panic::catch_unwind(AssertUnwindSafe(|| { | |
| let command = | |
| env.get_string(&command).expect("Could not get Java String for command").into(); | |
| let result = do_navigate_command(command); | |
| get_string_or_throw(&mut env, result) | |
| })); | |
| match result { | |
| Ok(s) => s, | |
| Err(_) => { | |
| let _ = env.throw_new("onl/mdw/mathcat4j/api/PanicException", "Panic in MathCAT"); | |
| JObject::null().into_raw() | |
| } | |
| } | |
| } | |
| #[unsafe(no_mangle)] | |
| pub extern "system" fn Java_onl_mdw_mathcat4j_api_MathCatJni_getNavigationMathml( | |
| mut env: JNIEnv, | |
| _obj: JObject, | |
| ) -> jobject { | |
| let result = panic::catch_unwind(AssertUnwindSafe(|| { | |
| let result = get_navigation_mathml(); | |
| get_navigation_position_or_throw(&mut env, "onl/mdw/mathcat4j/api/NavigationNode", result) | |
| })); | |
| match result { | |
| Ok(s) => s, | |
| Err(_) => { | |
| let _ = env.throw_new("onl/mdw/mathcat4j/api/PanicException", "Panic in MathCAT"); | |
| JObject::null().into_raw() | |
| } | |
| } | |
| } | |
| #[unsafe(no_mangle)] | |
| pub extern "system" fn Java_onl_mdw_mathcat4j_api_MathCatJni_getNavigationMathmlId( | |
| mut env: JNIEnv, | |
| _obj: JObject, | |
| ) -> jobject { | |
| let result = panic::catch_unwind(AssertUnwindSafe(|| { | |
| let result = get_navigation_mathml_id(); | |
| get_navigation_position_or_throw(&mut env, "onl/mdw/mathcat4j/api/NavigationId", result) | |
| })); | |
| match result { | |
| Ok(s) => s, | |
| Err(_) => { | |
| let _ = env.throw_new("onl/mdw/mathcat4j/api/PanicException", "Panic in MathCAT"); | |
| JObject::null().into_raw() | |
| } | |
| } | |
| } | |
| fn get_navigation_position_or_throw( | |
| env: &mut JNIEnv, | |
| cls: &str, | |
| result: Result<(String, usize), Error>, | |
| ) -> jobject { | |
| let signature = "(Ljava/lang/String;I)V"; | |
| match result { | |
| Ok((id, offset)) => { | |
| let id_jobject = | |
| JObject::from(env.new_string(id).expect("Unable to create Java string")); | |
| let arguments = | |
| &[JValue::from(&id_jobject), JValue::from(jint::try_from(offset).unwrap())]; | |
| env.new_object(cls, signature, arguments) | |
| .unwrap_or_else(|_| { | |
| if !env.exception_check().unwrap() { | |
| let _ = env.throw_new( | |
| "java/lang/RuntimeException", | |
| "Unknown error whilst creating object", | |
| ); | |
| } | |
| JObject::null() | |
| }) | |
| .into_raw() | |
| } | |
| Err(e) => { | |
| let _ = env.throw_new("java/lang/RuntimeException", errors_to_string(&e)); | |
| JObject::null().into_raw() | |
| } | |
| } | |
| } | |
| fn get_string_or_throw(env: &mut JNIEnv, result: Result<String, Error>) -> jstring { | |
| match result { | |
| Ok(s) => env.new_string(s).expect("Could not create Java String").into_raw(), | |
| Err(e) => { | |
| let _ = env.throw_new("java/lang/RuntimeException", errors_to_string(&e)); | |
| JObject::null().into_raw() | |
| } | |
| } | |
| } |