diff --git a/rust/examples/dhtnode.rs b/rust/examples/dhtnode.rs index a4589d37960794bac4c047ef25597c3cc7c6993e..88505b5f8e15948caae7938e5cc25c7711f60593 100644 --- a/rust/examples/dhtnode.rs +++ b/rust/examples/dhtnode.rs @@ -3,7 +3,7 @@ use std::ffi::CString; use std::{thread, time}; use libc::c_void; -use opendht::*; +use opendht::{InfoHash,DhtRunner,Value}; extern fn get_cb(v: *mut Value, ptr: *mut c_void) { if ptr.is_null() { @@ -15,6 +15,16 @@ extern fn get_cb(v: *mut Value, ptr: *mut c_void) { } } +extern fn value_cb(v: *mut Value, expired: bool, ptr: *mut c_void) { + if ptr.is_null() { + return; + } + let _handler: &mut Handler = unsafe { &mut *(ptr as *mut Handler) }; + unsafe { + println!("Got data: {} - expired: {}", *v, expired); + } +} + extern fn done_cb(ok: bool, ptr: *mut c_void) { let _handler: &mut Handler = unsafe { &mut *(ptr as *mut Handler) }; println!("In done - {}", ok); @@ -41,9 +51,15 @@ fn main() { let mut handler = Handler { _data: 8, }; + let ptr = &mut handler as *mut _ as *mut c_void; + + println!("Start listening /foo"); + let token = dht.listen(&InfoHash::get("foo"), value_cb, ptr); + thread::sleep(ten_secs); + println!("Stop listening /foo"); + dht.cancel_listen(&InfoHash::get("foo"), token); loop { println!("Get /alice"); - let ptr = &mut handler as *mut _ as *mut c_void; dht.get(&InfoHash::get("alice"), get_cb, done_cb, ptr); let v = Value::new("hi!"); dht.put(&InfoHash::get("bob"), Box::into_raw(v), done_cb, ptr); diff --git a/rust/src/ffi.rs b/rust/src/ffi.rs new file mode 100644 index 0000000000000000000000000000000000000000..f4b7801e83840ee556b5506f3f5633dd386ae8bf --- /dev/null +++ b/rust/src/ffi.rs @@ -0,0 +1,63 @@ +use libc::{c_char, c_void, in_port_t, size_t}; + +const HASH_LEN: usize = 20; + +#[repr(C)] +pub struct InfoHash +{ + pub d: [u8; HASH_LEN], +} + +#[repr(C)] +pub struct DhtRunner +{ + _opaque: [u8; 0] +} + +#[repr(C)] +pub struct Value +{ + _opaque: [u8; 0] +} + +#[repr(C)] +pub struct DataView +{ + pub data: *const u8, + pub size: size_t +} + + +#[repr(C)] +pub struct OpToken +{ + _opaque: [u8; 0] +} + + +#[link(name = "opendht-c")] +extern { + pub fn dht_infohash_print(h: *const InfoHash) -> *mut c_char; + pub fn dht_infohash_random(h: *mut InfoHash); + pub fn dht_infohash_get(h: *mut InfoHash, dat: *mut u8, dat_size: size_t); + + pub fn dht_value_get_data(data: *const Value) -> DataView; + pub fn dht_value_unref(data: *mut Value); + pub fn dht_value_new(data: *const u8, size: size_t) -> *mut Value; + + pub fn dht_runner_new() -> *mut DhtRunner; + pub fn dht_runner_delete(dht: *mut DhtRunner); + pub fn dht_runner_run(dht: *mut DhtRunner, port: in_port_t); + pub fn dht_runner_bootstrap(dht: *mut DhtRunner, host: *const c_char, service: *const c_char); + pub fn dht_runner_get(dht: *mut DhtRunner, h: *const InfoHash, + get_cb: extern fn(*mut Value, *mut c_void), + done_cb: extern fn(bool, *mut c_void), + cb_user_data: *mut c_void); + pub fn dht_runner_put(dht: *mut DhtRunner, h: *const InfoHash, v: *const Value, + done_cb: extern fn(bool, *mut c_void), + cb_user_data: *mut c_void); + pub fn dht_runner_listen(dht: *mut DhtRunner, h: *const InfoHash, + cb: extern fn(*mut Value, bool, *mut c_void), + cb_user_data: *mut c_void) -> *const OpToken; + pub fn dht_runner_cancel_listen(dht: *mut DhtRunner, h: *const InfoHash, token: *const OpToken); +} \ No newline at end of file diff --git a/rust/src/lib.rs b/rust/src/lib.rs index b8bb46b58f787f891a764952eb5539d3203f0de7..a0274aac255736298303f31cd3ef933002cf07a4 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1,62 +1,15 @@ extern crate libc; + +mod ffi; +use ffi::*; +pub use ffi::{ DhtRunner, InfoHash, Value}; + use std::fmt; use std::ffi::CStr; use std::ffi::CString; -use std::ptr; use std::str; use std::slice; -use libc::{c_char, c_void, in_port_t, size_t, uint8_t}; - -const HASH_LEN: usize = 20; - -#[repr(C)] -pub struct InfoHash -{ - d: [u8; HASH_LEN], -} - -#[repr(C)] -pub struct DhtRunner -{ - _opaque: [u8; 0] -} - -#[repr(C)] -pub struct Value -{ - _opaque: [u8; 0] -} - -#[repr(C)] -pub struct DataView -{ - data: *const uint8_t, - size: size_t -} - - -#[link(name = "opendht-c")] -extern { - fn dht_infohash_print(h: *const InfoHash) -> *mut c_char; - fn dht_infohash_random(h: *mut InfoHash); - fn dht_infohash_get(h: *mut InfoHash, dat: *mut uint8_t, dat_size: size_t); - - fn dht_value_get_data(data: *const Value) -> DataView; - fn dht_value_unref(data: *mut Value); - fn dht_value_new(data: *const uint8_t, size: size_t) -> *mut Value; - - fn dht_runner_new() -> *mut DhtRunner; - fn dht_runner_delete(dht: *mut DhtRunner); - fn dht_runner_run(dht: *mut DhtRunner, port: in_port_t); - fn dht_runner_bootstrap(dht: *mut DhtRunner, host: *const c_char, service: *const c_char); - fn dht_runner_get(dht: *mut DhtRunner, h: *const InfoHash, - get_cb: extern fn(*mut Value, *mut c_void), - done_cb: extern fn(bool, *mut c_void), - cb_user_data: *mut c_void); - fn dht_runner_put(dht: *mut DhtRunner, h: *const InfoHash, v: *const Value, - done_cb: extern fn(bool, *mut c_void), - cb_user_data: *mut c_void); -} +use libc::c_void; impl InfoHash { pub fn new() -> InfoHash { @@ -118,7 +71,7 @@ impl DhtRunner { get_cb: extern fn(*mut Value, *mut c_void), done_cb: extern fn(bool, *mut c_void), cb_user_data: *mut c_void) { - + unsafe { dht_runner_get(&mut *self, h, get_cb, done_cb, cb_user_data) } @@ -127,11 +80,26 @@ impl DhtRunner { pub fn put(&mut self, h: &InfoHash, v: *const Value, done_cb: extern fn(bool, *mut c_void), cb_user_data: *mut c_void) { - + unsafe { dht_runner_put(&mut *self, h, v, done_cb, cb_user_data) } } + + pub fn listen(&mut self, h: &InfoHash, + cb: extern fn(*mut Value, bool, *mut c_void), + cb_user_data: *mut c_void) -> *const OpToken { + unsafe { + dht_runner_listen(&mut *self, h, cb, cb_user_data) + } + } + + pub fn cancel_listen(&mut self, h: &InfoHash, token: *const OpToken) { + + unsafe { + dht_runner_cancel_listen(&mut *self, h, token) + } + } } impl Drop for DhtRunner {