Allow making direct RPC queries from the C API (#8588)
This commit is contained in:
committed by
Robert Habermeier
parent
fe5f5b28d9
commit
bd1e3fc606
@@ -86,6 +86,22 @@ int parity_start(const ParityParams* params, void** out);
|
||||
/// must not call this function.
|
||||
void parity_destroy(void* parity);
|
||||
|
||||
/// Performs an RPC request.
|
||||
///
|
||||
/// Blocks the current thread until the request is finished. You are therefore encouraged to spawn
|
||||
/// a new thread for each RPC request that requires accessing the blockchain.
|
||||
///
|
||||
/// - `rpc` and `len` must contain the JSON string representing the RPC request.
|
||||
/// - `out_str` and `out_len` point to a buffer where the output JSON result will be stored. If the
|
||||
/// buffer is not large enough, the function fails.
|
||||
/// - `out_len` will receive the final length of the string.
|
||||
/// - On success, the function returns 0. On failure, it returns 1.
|
||||
///
|
||||
/// **Important**: Keep in mind that this function doesn't write any null terminator on the output
|
||||
/// string.
|
||||
///
|
||||
int parity_rpc(void* parity, const char* rpc, size_t len, char* out_str, size_t* out_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -23,6 +23,7 @@ use std::os::raw::{c_char, c_void, c_int};
|
||||
use std::panic;
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
use std::str;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ParityParams {
|
||||
@@ -131,3 +132,33 @@ pub extern fn parity_destroy(client: *mut c_void) {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn parity_rpc(client: *mut c_void, query: *const char, len: usize, out_str: *mut c_char, out_len: *mut usize) -> c_int {
|
||||
unsafe {
|
||||
panic::catch_unwind(|| {
|
||||
let client: &mut parity::RunningClient = &mut *(client as *mut parity::RunningClient);
|
||||
|
||||
let query_str = {
|
||||
let string = slice::from_raw_parts(query as *const u8, len);
|
||||
match str::from_utf8(string) {
|
||||
Ok(a) => a,
|
||||
Err(_) => return 1,
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(output) = client.rpc_query_sync(query_str) {
|
||||
let q_out_len = output.as_bytes().len();
|
||||
if *out_len < q_out_len {
|
||||
return 1;
|
||||
}
|
||||
|
||||
ptr::copy_nonoverlapping(output.as_bytes().as_ptr(), out_str as *mut u8, q_out_len);
|
||||
*out_len = q_out_len;
|
||||
0
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}).unwrap_or(1)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user