use crate::*;
use runng_derive::NngMsgOpts;
use runng_sys::*;
use std::{os::raw::c_void, ptr, slice};
#[derive(Debug, NngMsgOpts)]
pub struct NngMsg {
msg: *mut nng_msg,
}
impl NngMsg {
pub fn new() -> Result<Self> {
NngMsg::with_capacity(0)
}
pub fn with_capacity(size_bytes: usize) -> Result<Self> {
unsafe {
let mut msg: *mut nng_msg = ptr::null_mut();
let res = nng_msg_alloc(&mut msg, size_bytes);
Error::zero_map(res, || NngMsg::from_raw(msg))
}
}
pub unsafe fn from_raw(msg: *mut nng_msg) -> NngMsg {
NngMsg { msg }
}
pub unsafe fn take(mut self) -> *mut nng_msg {
let msg = self.msg;
self.msg = ptr::null_mut();
msg
}
pub unsafe fn msg(&self) -> *mut nng_msg {
self.msg
}
pub fn as_slice(&self) -> &[u8] {
self.body()
}
pub fn as_mut_slice(&mut self) -> &mut [u8] {
unsafe {
let body = nng_msg_body(self.msg()) as *mut u8;
let len = nng_msg_len(self.msg());
slice::from_raw_parts_mut(body, len)
}
}
pub fn header(&self) -> &[u8] {
unsafe {
let header = nng_msg_header(self.msg()) as *mut u8;
let len = nng_msg_header_len(self.msg());
slice::from_raw_parts(header, len)
}
}
pub fn header_len(&self) -> usize {
unsafe { nng_msg_header_len(self.msg()) }
}
pub fn body(&self) -> &[u8] {
unsafe {
let body = nng_msg_body(self.msg()) as *mut u8;
let len = nng_msg_len(self.msg());
slice::from_raw_parts(body, len)
}
}
pub fn len(&self) -> usize {
unsafe { nng_msg_len(self.msg()) }
}
pub fn is_empty(&self) -> bool {
unsafe { nng_msg_len(self.msg()) == 0 }
}
pub fn append_slice(&mut self, data: &[u8]) -> Result<()> {
self.append_ptr(data.as_ptr(), data.len())
}
pub fn append_ptr(&mut self, data: *const u8, size: usize) -> Result<()> {
unsafe { nng_int_to_result(nng_msg_append(self.msg(), data as *const c_void, size)) }
}
pub fn insert_slice(&mut self, data: &[u8]) -> Result<()> {
self.insert_ptr(data.as_ptr(), data.len())
}
pub fn insert_ptr(&mut self, data: *const u8, size: usize) -> Result<()> {
unsafe { nng_int_to_result(nng_msg_insert(self.msg(), data as *const c_void, size)) }
}
pub fn trim(&mut self, size: usize) -> Result<()> {
unsafe { nng_int_to_result(nng_msg_trim(self.msg(), size)) }
}
pub fn chop(&mut self, size: usize) -> Result<()> {
unsafe { nng_int_to_result(nng_msg_chop(self.msg(), size)) }
}
pub fn header_append_slice(&mut self, data: &[u8]) -> Result<()> {
self.header_append_ptr(data.as_ptr(), data.len())
}
pub fn header_append_ptr(&mut self, data: *const u8, size: usize) -> Result<()> {
unsafe {
nng_int_to_result(nng_msg_header_append(
self.msg(),
data as *const c_void,
size,
))
}
}
pub fn header_insert_slice(&mut self, data: &[u8]) -> Result<()> {
self.header_insert_ptr(data.as_ptr(), data.len())
}
pub fn header_insert_ptr(&mut self, data: *const u8, size: usize) -> Result<()> {
unsafe {
nng_int_to_result(nng_msg_header_insert(
self.msg(),
data as *const c_void,
size,
))
}
}
pub fn header_trim(&mut self, size: usize) -> Result<()> {
unsafe { nng_int_to_result(nng_msg_header_trim(self.msg(), size)) }
}
pub fn header_chop(&mut self, size: usize) -> Result<()> {
unsafe { nng_int_to_result(nng_msg_header_chop(self.msg(), size)) }
}
pub fn dup(&self) -> Result<NngMsg> {
unsafe {
let mut msg: *mut nng_msg = ptr::null_mut();
let res = nng_msg_dup(&mut msg, self.msg());
Error::zero_map(res, || NngMsg::from_raw(msg))
}
}
pub fn clear(&mut self) {
unsafe {
nng_msg_clear(self.msg());
}
}
pub fn get_pipe(&self) -> Option<pipe::NngPipe> {
pipe::NngPipe::new(self)
}
pub fn set_pipe(&mut self, pipe: &pipe::NngPipe) {
unsafe {
nng_msg_set_pipe(self.msg(), pipe.nng_pipe());
}
}
}
impl AsRef<[u8]> for NngMsg {
fn as_ref(&self) -> &[u8] {
self.as_slice()
}
}
impl AsMut<[u8]> for NngMsg {
fn as_mut(&mut self) -> &mut [u8] {
self.as_mut_slice()
}
}
impl Clone for NngMsg {
fn clone(&self) -> Self {
self.dup().unwrap()
}
}
unsafe impl Send for NngMsg {}
unsafe impl Sync for NngMsg {}
impl PartialEq for NngMsg {
fn eq(&self, other: &NngMsg) -> bool {
self.header() == other.header() && self.body() == other.body()
}
}
impl Drop for NngMsg {
fn drop(&mut self) {
unsafe {
if !self.msg.is_null() {
trace!("Dropping {:x}", self.msg as u64);
nng_msg_free(self.msg);
}
}
}
}