zmq/
sockopt.rs

1use libc::{c_int, c_uint, size_t};
2use std::os::raw::c_void;
3use std::result;
4use std::string::FromUtf8Error;
5use std::{mem, ptr, str};
6
7use super::{PollEvents, Result};
8
9pub trait Getter
10where
11    Self: Sized,
12{
13    fn get(sock: *mut c_void, opt: c_int) -> Result<Self>;
14}
15
16pub trait Setter
17where
18    Self: Sized,
19{
20    fn set(sock: *mut c_void, opt: c_int, value: Self) -> Result<()>;
21}
22
23macro_rules! getsockopt_num(
24    ($c_ty:ty, $ty:ty) => (
25        impl Getter for $ty {
26            #[allow(trivial_casts)]
27            fn get(sock: *mut c_void, opt: c_int) -> Result<$ty> {
28                let mut value: $c_ty = 0;
29                let value_ptr = &mut value as *mut $c_ty;
30                let mut size = mem::size_of::<$c_ty>() as size_t;
31
32                zmq_try!(unsafe {
33                    zmq_sys::zmq_getsockopt(
34                        sock,
35                        opt,
36                        value_ptr as *mut c_void,
37                        &mut size)
38                });
39                Ok(value as $ty)
40            }
41        }
42    )
43);
44
45getsockopt_num!(c_int, i32);
46getsockopt_num!(c_uint, u32);
47getsockopt_num!(i64, i64);
48getsockopt_num!(u64, u64);
49
50pub fn get_bytes(sock: *mut c_void, opt: c_int, size: size_t) -> Result<Vec<u8>> {
51    let mut size = size;
52    let mut value = vec![0u8; size];
53
54    zmq_try!(unsafe {
55        zmq_sys::zmq_getsockopt(sock, opt, value.as_mut_ptr() as *mut c_void, &mut size)
56    });
57    value.truncate(size);
58    Ok(value)
59}
60
61pub fn get_string(
62    sock: *mut c_void,
63    opt: c_int,
64    size: size_t,
65    remove_nulbyte: bool,
66) -> Result<result::Result<String, Vec<u8>>> {
67    let mut value = get_bytes(sock, opt, size)?;
68
69    if remove_nulbyte {
70        value.pop();
71    }
72    Ok(String::from_utf8(value).map_err(FromUtf8Error::into_bytes))
73}
74
75macro_rules! setsockopt_num(
76    ($ty:ty) => (
77        impl Setter for $ty {
78            #[allow(trivial_casts)]
79            fn set(sock: *mut c_void, opt: c_int, value: $ty) -> Result<()> {
80                let size = mem::size_of::<$ty>() as size_t;
81
82                zmq_try!(unsafe {
83                    zmq_sys::zmq_setsockopt(
84                        sock,
85                        opt,
86                        (&value as *const $ty) as *const c_void,
87                        size)
88                });
89                Ok(())
90            }
91        }
92    )
93);
94
95setsockopt_num!(i32);
96setsockopt_num!(i64);
97setsockopt_num!(u64);
98
99fn setsockopt_null(sock: *mut c_void, opt: c_int) -> Result<()> {
100    zmq_try!(unsafe { zmq_sys::zmq_setsockopt(sock, opt, ptr::null(), 0) });
101    Ok(())
102}
103
104impl<'a> Setter for &'a str {
105    fn set(sock: *mut c_void, opt: c_int, value: Self) -> Result<()> {
106        set(sock, opt, value.as_bytes())
107    }
108}
109
110impl<'a> Setter for Option<&'a str> {
111    fn set(sock: *mut c_void, opt: c_int, value: Self) -> Result<()> {
112        if let Some(s) = value {
113            set(sock, opt, s.as_bytes())
114        } else {
115            setsockopt_null(sock, opt)
116        }
117    }
118}
119
120impl Getter for bool {
121    fn get(sock: *mut c_void, opt: c_int) -> Result<Self> {
122        let result: i32 = get(sock, opt)?;
123        Ok(result == 1)
124    }
125}
126
127impl Setter for bool {
128    fn set(sock: *mut c_void, opt: c_int, value: Self) -> Result<()> {
129        set(sock, opt, if value { 1i32 } else { 0i32 })
130    }
131}
132
133impl<'a> Setter for &'a [u8] {
134    fn set(sock: *mut c_void, opt: c_int, value: &'a [u8]) -> Result<()> {
135        zmq_try!(unsafe {
136            zmq_sys::zmq_setsockopt(
137                sock,
138                opt,
139                value.as_ptr() as *const c_void,
140                value.len() as size_t,
141            )
142        });
143        Ok(())
144    }
145}
146
147impl Getter for PollEvents {
148    fn get(sock: *mut c_void, opt: c_int) -> Result<Self> {
149        get::<c_int>(sock, opt).map(|bits| PollEvents::from_bits_truncate(bits as i16))
150    }
151}
152
153pub fn get<T: Getter>(sock: *mut c_void, opt: c_int) -> Result<T> {
154    T::get(sock, opt)
155}
156
157pub fn set<T: Setter>(sock: *mut c_void, opt: c_int, value: T) -> Result<()> {
158    T::set(sock, opt, value)
159}