From c2dbf2c3040d05b8dfe888e305f4b691e774b952 Mon Sep 17 00:00:00 2001 From: Emily Toop Date: Fri, 11 May 2018 12:23:32 +0100 Subject: [PATCH] Return `&str` from `c_char_to_string` rather than `String` to avoid unnecessary allocations. --- ffi/src/lib.rs | 6 +++--- ffi/src/utils.rs | 9 ++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/ffi/src/lib.rs b/ffi/src/lib.rs index 037c9771..3b77ad33 100644 --- a/ffi/src/lib.rs +++ b/ffi/src/lib.rs @@ -296,7 +296,7 @@ pub unsafe extern "C" fn tx_report_get_tx_instant(tx_report: *mut TxReport) -> c pub unsafe extern "C" fn tx_report_entity_for_temp_id(tx_report: *mut TxReport, tempid: *const c_char) -> *mut c_longlong { let tx_report = &*tx_report; let key = c_char_to_string(tempid); - if let Some(entid) = tx_report.tempids.get(&key) { + if let Some(entid) = tx_report.tempids.get(key) { Box::into_raw(Box::new(entid.clone() as c_longlong)) } else { std::ptr::null_mut() @@ -853,14 +853,14 @@ pub unsafe extern "C" fn store_register_observer(store: *mut Store, }; callback(string_to_c_char(obs_key), &reports); })); - store.register_observer(key, tx_observer); + store.register_observer(key.to_string(), tx_observer); } /// Unregisters a [TxObserver](mentat::TxObserver) with the `key` to observe changes on this `store`. #[no_mangle] pub unsafe extern "C" fn store_unregister_observer(store: *mut Store, key: *const c_char) { let store = &mut*store; - let key = c_char_to_string(key); + let key = c_char_to_string(key).to_string(); store.unregister_observer(&key); } diff --git a/ffi/src/utils.rs b/ffi/src/utils.rs index 76aeee47..1a4abbf5 100644 --- a/ffi/src/utils.rs +++ b/ffi/src/utils.rs @@ -19,19 +19,18 @@ pub mod strings { Keyword, }; - pub fn c_char_to_string(cchar: *const c_char) -> String { + pub fn c_char_to_string(cchar: *const c_char) -> &'static str { let c_str = unsafe { CStr::from_ptr(cchar) }; - let r_str = c_str.to_str().unwrap_or(""); - r_str.to_string() + c_str.to_str().unwrap_or("") } pub fn string_to_c_char(r_string: T) -> *mut c_char where T: Into { CString::new(r_string.into()).unwrap().into_raw() } + pub fn kw_from_string(keyword_string: &'static str) -> NamespacedKeyword { // TODO: validate. The input might not be a keyword! - pub fn kw_from_string(mut keyword_string: String) -> Keyword { - let attr_name = keyword_string.split_off(1); + let attr_name = keyword_string.trim_left_matches(":"); let parts: Vec<&str> = attr_name.split("/").collect(); Keyword::namespaced(parts[0], parts[1]) }