ZeroTierOne/rust-zerotier-core/src/buffer.rs
2021-01-20 00:02:39 -05:00

82 lines
2.5 KiB
Rust

/*
* Copyright (c)2013-2020 ZeroTier, Inc.
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file in the project's root directory.
*
* Change Date: 2025-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2.0 of the Apache License.
*/
/****/
use std::os::raw::c_void;
use crate::bindings::capi as ztcore;
/// A reusable buffer for I/O to/from the ZeroTier core.
/// The core allocates and manages a pool of these. This provides a Rust
/// interface to that pool. ZT core buffers are used to reduce the need for
/// memory copying by passing buffers around instead of memcpy'ing when
/// packet data is passed into and out of the core.
pub struct Buffer {
pub(crate) zt_core_buf: *mut u8,
pub(crate) data_size: usize,
}
impl Buffer {
/// Maximum capacity of a ZeroTier reusable buffer.
pub const CAPACITY: usize = ztcore::ZT_BUF_SIZE as usize;
/// Obtain a new buffer from the core and set the size of its data to CAPACITY.
/// The contents of the buffer are not defined.
#[inline(always)]
pub fn new() -> Buffer {
let b = unsafe { ztcore::ZT_getBuffer() as *mut u8 };
if b.is_null() {
panic!("out of memory calling ZT_getBuffer()");
}
Buffer {
zt_core_buf: b,
data_size: ztcore::ZT_BUF_SIZE as usize
}
}
/// Get the current size of the data held by this buffer.
/// Initially this is equal to CAPACITY.
#[inline(always)]
pub fn len(&self) -> usize {
self.data_size
}
#[inline(always)]
pub fn as_ptr(&self) -> *const u8 {
self.zt_core_buf
}
#[inline(always)]
pub fn as_mut_ptr(&mut self) -> *mut u8 {
self.zt_core_buf
}
/// Set the size of the data held by this buffer. This is unsafe because
/// setting it to a value larger than CAPACITY will place the buffer into
/// an invalid state.
#[inline(always)]
pub unsafe fn set_len(&mut self, s: usize) {
self.data_size = s;
}
}
impl Drop for Buffer {
fn drop(&mut self) {
// NOTE: in node.rs std::mem::forget() is used to prevent this from
// being called on buffers that have been returned via one of the
// process_XX() methods on ZT_Node. This destructor only exists to
// return buffers that were not consumed normally.
unsafe {
ztcore::ZT_freeBuffer(self.zt_core_buf as *mut c_void);
}
}
}