websocket_std/ffi/sync/
client.rs

1use super::super::super::sync::client::{Config, WSEvent as RWSEvent, WSClient};
2use std::ffi::{c_void, c_char, CStr};
3use std::alloc::{alloc, Layout};
4use std::mem;
5use std::ptr;
6use std::str;
7use super::super::common;
8
9#[no_mangle]
10extern "C" fn wssclient_new<'a>() -> *mut WSClient<'a, *mut c_void> {
11    // Box doesn't return a Result type, that the reason to use layout, to check if the system
12    // gave me memory to store the client.
13    let size = mem::size_of::<WSClient<*mut c_void>>();
14    let aling = std::mem::align_of::<WSClient<*mut c_void>>();
15    let layout = Layout::from_size_align(size, aling);
16
17    if layout.is_err() {
18        return std::ptr::null_mut();
19    }
20
21    let ptr = unsafe { alloc(layout.unwrap()) };
22    let client = WSClient::<*mut c_void>::new();
23
24    unsafe {
25        ptr::copy_nonoverlapping(&client, ptr as *mut WSClient<*mut c_void>, 1);
26    }
27
28    ptr as *mut WSClient<*mut c_void>
29}
30
31#[no_mangle]
32unsafe extern "C" fn wssclient_init<'a> (
33    client: *mut WSClient<'a, *mut c_void>,
34    host: *const c_char,
35    port: u16,
36    path: *const c_char,
37    callback: *mut c_void,
38) {
39    let host = str::from_utf8(CStr::from_ptr(host).to_bytes()).unwrap();
40    let path = str::from_utf8(CStr::from_ptr(path).to_bytes()).unwrap();
41
42    let callback: fn(&mut WSClient<'a, *mut c_void>, &RWSEvent, Option<*mut c_void>) = mem::transmute(callback);
43    let config = Config { callback: Some(callback), data: None, protocols: None };
44    
45    let client = &mut *client;
46
47    client.init(host, port, path, Some(config));
48}
49
50#[no_mangle]
51unsafe extern "C" fn wssclient_loop<'a>(client: *mut WSClient<'a, *mut c_void>) -> common::WSStatus {
52    let client = &mut *client;
53
54    match client.event_loop() {
55        Ok(_) => {}
56        Err(e) => {
57            return common::rust_error_to_c_error(e);
58        } 
59    }
60
61    common::WSStatus::OK
62}
63
64#[no_mangle]
65unsafe extern "C" fn wssclient_send<'a>(client: *mut WSClient<'a, *mut c_void>, message: *const c_char) {
66    let msg = str::from_utf8(CStr::from_ptr(message).to_bytes()).unwrap();
67    let client = &mut *client;
68    client.send(msg);
69}
70
71#[no_mangle]
72extern "C" fn wssclient_drop<'a>(client: *mut WSClient<'a, *mut c_void>) {
73    // Create a box from the raw pointer, at the end of the function the client will be dropped and the memory will be free.
74    unsafe {
75        let _c = Box::from_raw(client);
76    }
77}