2019-08-14 22:15:38 +03:00
|
|
|
use log;
|
|
|
|
|
|
|
|
use crate::api::AppResult;
|
|
|
|
use crate::errors::err_msg;
|
|
|
|
use crate::ffi;
|
|
|
|
|
|
|
|
pub fn query(query: String) -> AppResult<String> {
|
|
|
|
log::debug!("executing query: '{}'", query);
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
let bytes = query.as_bytes();
|
|
|
|
let query_ptr = ffi::allocate(bytes.len());
|
|
|
|
|
|
|
|
for (i, byte) in bytes.iter().enumerate() {
|
|
|
|
let ptr = query_ptr + i as i32;
|
|
|
|
ffi::store(ptr, *byte);
|
|
|
|
}
|
|
|
|
|
|
|
|
let result_ptr = ffi::invoke(query_ptr, bytes.len());
|
|
|
|
|
2019-08-14 23:50:29 +03:00
|
|
|
let mut result_size: usize = 0;
|
|
|
|
for i in 0..3 {
|
2019-08-14 22:15:38 +03:00
|
|
|
let ptr = result_ptr + i as i32;
|
2019-08-14 23:50:29 +03:00
|
|
|
let b = ffi::load(ptr) as usize;
|
|
|
|
result_size = result_size + (b << (8 * i));
|
2019-08-14 22:15:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
let mut result_bytes = vec![0; result_size as usize];
|
2019-08-14 23:50:29 +03:00
|
|
|
for i in 4..(result_size + 4) {
|
2019-08-14 22:15:38 +03:00
|
|
|
let ptr = result_ptr + i as i32;
|
|
|
|
let b = ffi::load(ptr);
|
|
|
|
result_bytes[i as usize - 4] = b;
|
|
|
|
}
|
|
|
|
|
|
|
|
let result_str = std::str::from_utf8(result_bytes.as_slice());
|
|
|
|
if result_str.is_err() {
|
|
|
|
log::error!("unable to decode result from bytes: {:#x?}", result_bytes);
|
|
|
|
}
|
|
|
|
|
2019-08-14 23:22:15 +03:00
|
|
|
result_str
|
|
|
|
.map_err(|e| {
|
|
|
|
err_msg(&format!(
|
|
|
|
"unable to decode result from bytes {:#x?}: {}",
|
|
|
|
result_bytes, e
|
|
|
|
))
|
|
|
|
})
|
|
|
|
.map(|s| s.to_string())
|
2019-08-14 22:15:38 +03:00
|
|
|
}
|
|
|
|
}
|