| /* |
| * 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() |
| } |
| } |
| } |