1
0
mirror of https://github.com/ndarilek/tts-rs.git synced 2024-11-25 14:39:37 +00:00

FFI: Make all functions with unsafe blocks completely unsafe.

This is better than using unsafe blocks inside the functions, as that
tells the compiler that the unsafeness won't leak out of the block,
which isn't true in this case as we're dealing with another unsafe
language.
This commit is contained in:
mcb2003 2020-12-12 19:37:44 +00:00 committed by michael Connor buchan
parent 0905f6d6c6
commit 729ece9a07

View File

@ -69,20 +69,18 @@ pub extern "C" fn tts_default() -> *mut TTS {
/// Free the memory associated with a TTS object. /// Free the memory associated with a TTS object.
/// If `tts` is a null pointer, this function does nothing. /// If `tts` is a null pointer, this function does nothing.
#[no_mangle] #[no_mangle]
pub extern "C" fn tts_free(tts: *mut TTS) { pub unsafe extern "C" fn tts_free(tts: *mut TTS) {
if tts.is_null() { if tts.is_null() {
return; return;
} }
unsafe { Box::from_raw(tts); // Goes out of scope and is dropped
Box::from_raw(tts); // Goes out of scope and is dropped
}
} }
/// Returns the features supported by this TTS engine. /// Returns the features supported by this TTS engine.
/// `tts` must be a valid pointer to a TTS object. /// `tts` must be a valid pointer to a TTS object.
#[no_mangle] #[no_mangle]
pub extern "C" fn tts_supported_features(tts: *mut TTS) -> Features { pub unsafe extern "C" fn tts_supported_features(tts: *mut TTS) -> Features {
unsafe { tts.as_ref().unwrap().supported_features() } tts.as_ref().unwrap().supported_features()
} }
/// Speaks the specified text, optionally interrupting current speech. /// Speaks the specified text, optionally interrupting current speech.
@ -90,7 +88,7 @@ pub extern "C" fn tts_supported_features(tts: *mut TTS) -> Features {
/// the backend doesn't provide one). /// the backend doesn't provide one).
/// Returns true on success, false on error or if `tts` is NULL. /// Returns true on success, false on error or if `tts` is NULL.
#[no_mangle] #[no_mangle]
pub extern "C" fn tts_speak( pub unsafe extern "C" fn tts_speak(
tts: *mut TTS, tts: *mut TTS,
text: *const c_char, text: *const c_char,
interrupt: bool, interrupt: bool,
@ -99,22 +97,20 @@ pub extern "C" fn tts_speak(
if tts.is_null() { if tts.is_null() {
return true; return true;
} }
unsafe { let text = CStr::from_ptr(text).to_string_lossy().into_owned();
let text = CStr::from_ptr(text).to_string_lossy().into_owned(); match tts.as_mut().unwrap().speak(text, interrupt) {
match tts.as_mut().unwrap().speak(text, interrupt) { Ok(u) => {
Ok(u) => { if !utterance.is_null() {
if !utterance.is_null() { *utterance = match u {
*utterance = match u { Some(u) => Box::into_raw(Box::new(u)),
Some(u) => Box::into_raw(Box::new(u)), None => ptr::null_mut(),
None => ptr::null_mut(), };
};
}
return true;
}
Err(e) => {
set_last_error(e.to_string()).unwrap();
return false;
} }
return true;
}
Err(e) => {
set_last_error(e.to_string()).unwrap();
return false;
} }
} }
} }
@ -122,22 +118,20 @@ pub extern "C" fn tts_speak(
/// Free the memory associated with an `UtteranceId`. /// Free the memory associated with an `UtteranceId`.
/// Does nothing if `utterance` is NULL. /// Does nothing if `utterance` is NULL.
#[no_mangle] #[no_mangle]
pub extern "C" fn tts_free_utterance(utterance: *mut UtteranceId) { pub unsafe extern "C" fn tts_free_utterance(utterance: *mut UtteranceId) {
if utterance.is_null() { if utterance.is_null() {
return; return;
} }
unsafe { Box::from_raw(utterance);
Box::from_raw(utterance);
}
} }
/// Stops current speech. /// Stops current speech.
/// Returns true on success, false on error or if `tts` is NULL. /// Returns true on success, false on error or if `tts` is NULL.
#[no_mangle] #[no_mangle]
pub extern "C" fn tts_stop(tts: *mut TTS) -> bool { pub unsafe extern "C" fn tts_stop(tts: *mut TTS) -> bool {
if tts.is_null() { if tts.is_null() {
return false; return false;
} }
match unsafe { tts.as_mut().unwrap().stop() } { match tts.as_mut().unwrap().stop() {
Ok(_) => true, Ok(_) => true,
Err(e) => { Err(e) => {
set_last_error(e.to_string()).unwrap(); set_last_error(e.to_string()).unwrap();