Move CString-creation methods to TypedValue.

This commit is contained in:
Richard Newman 2018-04-25 13:45:31 -07:00
parent 5440efa4bf
commit a6ec3f2272
3 changed files with 70 additions and 27 deletions

View file

@ -8,6 +8,11 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use ::std::ffi::{
CString,
};
use ::std::os::raw::c_char;
use ::std::rc::{
Rc,
};
@ -525,6 +530,54 @@ impl TypedValue {
}
}
pub fn into_c_string(self) -> Option<*mut c_char> {
match self {
TypedValue::String(v) => {
// Get an independent copy of the string.
let s: String = v.cloned();
// Make a CString out of the new bytes.
let c: CString = CString::new(s).expect("String conversion failed!");
// Return a C-owned pointer.
Some(c.into_raw())
},
_ => None,
}
}
pub fn into_kw_c_string(self) -> Option<*mut c_char> {
match self {
TypedValue::Keyword(v) => {
// Get an independent copy of the string.
let s: String = v.to_string();
// Make a CString out of the new bytes.
let c: CString = CString::new(s).expect("String conversion failed!");
// Return a C-owned pointer.
Some(c.into_raw())
},
_ => None,
}
}
pub fn into_uuid_c_string(self) -> Option<*mut c_char> {
match self {
TypedValue::Uuid(v) => {
// Get an independent copy of the string.
let s: String = v.hyphenated().to_string();
// Make a CString out of the new bytes.
let c: CString = CString::new(s).expect("String conversion failed!");
// Return a C-owned pointer.
Some(c.into_raw())
},
_ => None,
}
}
pub fn into_uuid(self) -> Option<Uuid> {
match self {
TypedValue::Uuid(v) => Some(v),

View file

@ -52,7 +52,6 @@ pub mod utils;
pub use utils::strings::{
c_char_to_string,
c_char_from_rc,
kw_from_string,
string_to_c_char,
};
@ -276,7 +275,7 @@ pub unsafe extern "C" fn typed_value_as_entid(typed_value: *mut TypedValue) ->
#[no_mangle]
pub unsafe extern "C" fn typed_value_as_kw(typed_value: *mut TypedValue) -> *const c_char {
let typed_value = Box::from_raw(typed_value);
string_to_c_char(typed_value.into_kw().expect("Typed value cannot be coerced into a Namespaced Keyword").to_string())
typed_value.into_kw_c_string().expect("Typed value cannot be coerced into a Namespaced Keyword")
}
//as_boolean
@ -305,20 +304,20 @@ pub unsafe extern "C" fn typed_value_as_timestamp(typed_value: *mut TypedValue)
#[no_mangle]
pub unsafe extern "C" fn typed_value_as_string(typed_value: *mut TypedValue) -> *const c_char {
let typed_value = Box::from_raw(typed_value);
c_char_from_rc(typed_value.into_string().expect("Typed value cannot be coerced into a String"))
typed_value.into_c_string().expect("Typed value cannot be coerced into a String")
}
//as_uuid
#[no_mangle]
pub unsafe extern "C" fn typed_value_as_uuid(typed_value: *mut TypedValue) -> *const c_char {
let typed_value = Box::from_raw(typed_value);
string_to_c_char(typed_value.into_uuid_string().expect("Typed value cannot be coerced into a Uuid"))
typed_value.into_uuid_c_string().expect("Typed value cannot be coerced into a String")
}
#[no_mangle]
pub unsafe extern "C" fn row_at_index(rows: *mut Vec<Vec<TypedValue>>, index: c_int) -> *mut Vec<TypedValue> {
let result = &*rows;
result.get(index as usize).map_or(std::ptr::null_mut(), |v| Box::into_raw(Box::new(v.clone())))
result.get(index as usize).map_or_else(std::ptr::null_mut, |v| Box::into_raw(Box::new(v.clone())))
}
#[no_mangle]
@ -342,62 +341,62 @@ pub unsafe extern "C" fn values_iter(values: *mut Vec<TypedValue>) -> *mut Type
#[no_mangle]
pub unsafe extern "C" fn values_iter_next(iter: *mut TypedValueIterator) -> *const TypedValue {
let iter = &mut *iter;
iter.next().map_or(std::ptr::null_mut(), |v| &v as *const TypedValue)
iter.next().map_or_else(std::ptr::null, |v| &v as *const TypedValue)
}
//as_long
#[no_mangle]
pub unsafe extern "C" fn values_iter_next_as_long(iter: *mut TypedValueIterator) -> *const i64 {
let iter = &mut *iter;
iter.next().map_or(std::ptr::null_mut(), |v| &v.into_long().expect("Typed value cannot be coerced into a Long") as *const i64)
iter.next().map_or_else(std::ptr::null, |v| &v.into_long().expect("Typed value cannot be coerced into a Long") as *const i64)
}
// as ref
#[no_mangle]
pub unsafe extern "C" fn values_iter_next_as_entid(iter: *mut TypedValueIterator) -> *const Entid {
let iter = &mut *iter;
iter.next().map_or(std::ptr::null_mut(), |v| &v.into_entid().expect("Typed value cannot be coerced into am Entid") as *const Entid)
iter.next().map_or_else(std::ptr::null, |v| &v.into_entid().expect("Typed value cannot be coerced into am Entid") as *const Entid)
}
// as kw
#[no_mangle]
pub unsafe extern "C" fn values_iter_next_as_kw(iter: *mut TypedValueIterator) -> *const c_char {
let iter = &mut *iter;
iter.next().map_or(std::ptr::null_mut(), |v| string_to_c_char(v.into_kw().expect("Typed value cannot be coerced into a Namespaced Keyword").to_string()))
iter.next().map_or_else(std::ptr::null, |v| v.into_kw_c_string().expect("Typed value cannot be coerced into a Namespaced Keyword"))
}
//as_boolean
#[no_mangle]
pub unsafe extern "C" fn values_iter_next_as_boolean(iter: *mut TypedValueIterator) -> *const bool {
let iter = &mut *iter;
iter.next().map_or(std::ptr::null_mut(), |v| &v.into_boolean().expect("Typed value cannot be coerced into a Boolean") as *const bool)
iter.next().map_or_else(std::ptr::null, |v| &v.into_boolean().expect("Typed value cannot be coerced into a Boolean") as *const bool)
}
//as_double
#[no_mangle]
pub unsafe extern "C" fn values_iter_next_as_double(iter: *mut TypedValueIterator) -> *const f64 {
let iter = &mut *iter;
iter.next().map_or(std::ptr::null_mut(), |v| &v.into_double().expect("Typed value cannot be coerced into a Double") as *const f64)
iter.next().map_or_else(std::ptr::null, |v| &v.into_double().expect("Typed value cannot be coerced into a Double") as *const f64)
}
//as_timestamp
#[no_mangle]
pub unsafe extern "C" fn values_iter_next_as_timestamp(iter: *mut TypedValueIterator) -> *const i64 {
let iter = &mut *iter;
iter.next().map_or(std::ptr::null_mut(), |v| v.into_timestamp().expect("Typed value cannot be coerced into a Timestamp") as *const i64)
iter.next().map_or_else(std::ptr::null, |v| v.into_timestamp().expect("Typed value cannot be coerced into a Timestamp") as *const i64)
}
//as_string
#[no_mangle]
pub unsafe extern "C" fn values_iter_next_as_string(iter: *mut TypedValueIterator) -> *const c_char {
let iter = &mut *iter;
iter.next().map_or(std::ptr::null_mut(), |v| c_char_from_rc(v.into_string().expect("Typed value cannot be coerced into a String")))
iter.next().map_or_else(std::ptr::null, |v| v.into_c_string().expect("Typed value cannot be coerced into a String"))
}
//as_uuid
#[no_mangle]
pub unsafe extern "C" fn values_iter_next_as_uuid(iter: *mut TypedValueIterator) -> *const c_char {
let iter = &mut *iter;
iter.next().map_or(std::ptr::null_mut(), |v| string_to_c_char(v.into_uuid_string().expect("Typed value cannot be coerced into a Uuid")))
iter.next().map_or_else(std::ptr::null, |v| v.into_uuid_c_string().expect("Typed value cannot be coerced into a Uuid"))
}
#[no_mangle]
@ -426,7 +425,7 @@ pub unsafe extern "C" fn value_at_index_as_entid(values: *mut Vec<TypedValue>, i
pub unsafe extern "C" fn value_at_index_as_kw(values: *mut Vec<TypedValue>, index: c_int) -> *const c_char {
let result = &*values;
let value = result.get(index as usize).expect("No value at index");
string_to_c_char(value.clone().into_kw().expect("Typed value cannot be coerced into a Namespaced Keyword").to_string())
value.clone().into_kw_c_string().expect("Typed value cannot be coerced into a Namespaced Keyword")
}
//as_boolean
@ -458,7 +457,7 @@ pub unsafe extern "C" fn value_at_index_as_timestamp(values: *mut Vec<TypedValue
pub unsafe extern "C" fn value_at_index_as_string(values: *mut Vec<TypedValue>, index: c_int) -> *mut c_char {
let result = &*values;
let value = result.get(index as usize).expect("No value at index");
c_char_from_rc(value.clone().into_string().expect("Typed value cannot be coerced into a String"))
value.clone().into_c_string().expect("Typed value cannot be coerced into a String")
}
//as_uuid
@ -466,7 +465,7 @@ pub unsafe extern "C" fn value_at_index_as_string(values: *mut Vec<TypedValue>,
pub unsafe extern "C" fn value_at_index_as_uuid(values: *mut Vec<TypedValue>, index: c_int) -> *mut c_char {
let result = &*values;
let value = result.get(index as usize).expect("No value at index");
string_to_c_char(value.clone().into_uuid_string().expect("Typed value cannot be coerced into a Uuid"))
value.clone().into_uuid_c_string().expect("Typed value cannot be coerced into a Uuid")
}
// TODO: q_prepare

View file

@ -9,13 +9,11 @@
// specific language governing permissions and limitations under the License.
pub mod strings {
use std;
use std::ffi::{
CString,
CStr
};
use std::os::raw::c_char;
use std::rc::Rc;
use mentat::{
NamespacedKeyword,
@ -31,19 +29,12 @@ pub mod strings {
CString::new(r_string.into()).unwrap().into_raw()
}
// TODO: validate. The input might not be a keyword!
pub fn kw_from_string(mut keyword_string: String) -> NamespacedKeyword {
let attr_name = keyword_string.split_off(1);
let parts: Vec<&str> = attr_name.split("/").collect();
NamespacedKeyword::new(parts[0], parts[1])
}
pub fn c_char_from_rc(rc_string: Rc<String>) -> *mut c_char {
if let Some(str_ptr) = unsafe { Rc::into_raw(rc_string).as_ref() } {
string_to_c_char(str_ptr.clone())
} else {
std::ptr::null_mut()
}
}
}
pub mod log {