use std::ffi::CStr;
use std::ptr;
use libc;
use ::StringMap;
#[allow(non_camel_case_types)]
#[repr(C)]
pub struct stringmap_t(StringMap);
#[no_mangle]
pub unsafe extern "C" fn stringmap_new(count: libc::size_t,
keys: *const *const libc::c_char,
values: *const *const libc::c_char)
-> *mut stringmap_t {
let n = count as isize;
let mut data = Vec::default();
if keys.is_null() || values.is_null() {
return ptr::null_mut();
}
for (k, v) in (0..n).map(|i| (*keys.offset(i), *values.offset(i))) {
if k.is_null() || v.is_null() {
return ptr::null_mut();
}
data.push((CStr::from_ptr(k).to_string_lossy(),
CStr::from_ptr(v).to_string_lossy()));
}
Box::into_raw(Box::new(stringmap_t(StringMap::new(&data))))
}
#[no_mangle]
pub unsafe extern "C" fn stringmap_keys(m: *const stringmap_t)
-> *const *const libc::c_char {
m.as_ref().map(|this| this.0.keys.as_ptr()).unwrap_or(ptr::null())
}
#[no_mangle]
pub unsafe extern "C" fn stringmap_get(m: *const stringmap_t,
key: *const libc::c_char)
-> *const libc::c_char {
if let Some(this) = m.as_ref() {
let k = CStr::from_ptr(key).to_string_lossy();
this.0
.get(&k)
.map(|s| s.as_ptr() as *const libc::c_char)
.unwrap_or(ptr::null())
} else {
ptr::null()
}
}
#[no_mangle]
pub unsafe extern "C" fn stringmap_len(m: *const stringmap_t) -> libc::size_t {
m.as_ref().map(|this| this.0.len()).unwrap_or(0)
}
#[no_mangle]
pub unsafe extern "C" fn stringmap_free(m: *mut stringmap_t) { drop(m); }
unsafe fn drop<T>(ptr: *mut T) {
if !ptr.is_null() {
Box::from_raw(ptr);
}
}