more documentation

This commit is contained in:
Vinzenz Schroeter 2024-05-28 20:37:55 +02:00
parent daaa31a276
commit d351eef6fa
6 changed files with 194 additions and 22 deletions

View file

@ -1,6 +1,6 @@
use crate::DataRef; use crate::DataRef;
/// A vector of bits /// A fixed-size vector of bits
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct BitVec { pub struct BitVec {
size: usize, size: usize,
@ -8,17 +8,17 @@ pub struct BitVec {
} }
impl BitVec { impl BitVec {
/// Create a new bit vector. /// Create a new `BitVec`.
/// ///
/// # Arguments /// # Arguments
/// ///
/// * `size`: size in bits. Must be dividable by 8. /// * `size`: size in bits.
/// ///
/// returns: bit vector with all bits set to false. /// returns: `BitVec` with all bits set to false.
/// ///
/// # Panics /// # Panics
/// ///
/// When size is not a multiple of 8. /// When `size` is not divisible by 8.
#[must_use] #[must_use]
pub fn new(size: usize) -> BitVec { pub fn new(size: usize) -> BitVec {
assert_eq!(size % 8, 0); assert_eq!(size % 8, 0);
@ -36,6 +36,10 @@ impl BitVec {
/// * `value`: the value to set the bit to /// * `value`: the value to set the bit to
/// ///
/// returns: old value of the bit /// returns: old value of the bit
///
/// # Panics
///
/// When accessing `index` out of bounds.
pub fn set(&mut self, index: usize, value: bool) -> bool { pub fn set(&mut self, index: usize, value: bool) -> bool {
let (byte_index, bit_mask) = self.get_indexes(index); let (byte_index, bit_mask) = self.get_indexes(index);
@ -58,6 +62,10 @@ impl BitVec {
/// * `index`: the bit index to read /// * `index`: the bit index to read
/// ///
/// returns: value of the bit /// returns: value of the bit
///
/// # Panics
///
/// When accessing `index` out of bounds.
#[must_use] #[must_use]
pub fn get(&self, index: usize) -> bool { pub fn get(&self, index: usize) -> bool {
let (byte_index, bit_mask) = self.get_indexes(index); let (byte_index, bit_mask) = self.get_indexes(index);

View file

@ -52,6 +52,18 @@ impl Grid<u8> for ByteGrid {
} }
} }
/// Sets the value of the cell at the specified position in the `ByteGrid.
///
/// # Arguments
///
/// * `x` and `y`: position of the cell
/// * `value`: the value to write to the cell
///
/// returns: old value of the cell.
///
/// # Panics
///
/// When accessing `x` or `y` out of bounds.
fn set(&mut self, x: usize, y: usize, value: u8) -> u8 { fn set(&mut self, x: usize, y: usize, value: u8) -> u8 {
self.check_indexes(x, y); self.check_indexes(x, y);
let pos = &mut self.data[x + y * self.width]; let pos = &mut self.data[x + y * self.width];
@ -60,6 +72,15 @@ impl Grid<u8> for ByteGrid {
old_val old_val
} }
/// Gets the current value at the specified position.
///
/// # Arguments
///
/// * `x` and `y`: position of the cell to read
///
/// # Panics
///
/// When accessing `x` or `y` out of bounds.
fn get(&self, x: usize, y: usize) -> u8 { fn get(&self, x: usize, y: usize) -> u8 {
self.check_indexes(x, y); self.check_indexes(x, y);
self.data[x + y * self.width] self.data[x + y * self.width]

View file

@ -4,11 +4,20 @@ use servicepoint::DataRef;
use crate::c_slice::CByteSlice; use crate::c_slice::CByteSlice;
/// Creates a new `BitVec` instance. /// Creates a new `BitVec` instance.
/// The returned instance has to be freed with `bit_vec_dealloc`. ///
/// # Arguments
///
/// * `size`: size in bits.
///
/// returns: `BitVec` with all bits set to false.
///
/// # Panics
///
/// When `size` is not divisible by 8.
/// ///
/// # Safety /// # Safety
/// ///
/// The caller has to make sure that:7 /// The caller has to make sure that:
/// ///
/// - the returned instance is freed in some way, either by using a consuming function or /// - the returned instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_bit_vec_dealloc`. /// by explicitly calling `sp_bit_vec_dealloc`.
@ -17,7 +26,7 @@ pub unsafe extern "C" fn sp_bit_vec_new(size: usize) -> *mut BitVec {
Box::into_raw(Box::new(BitVec::new(size))) Box::into_raw(Box::new(BitVec::new(size)))
} }
/// Loads a `BitVec` from the provided data. /// Interpret the data as a series of bits and load then into a new `BitVec` instance.
/// ///
/// # Safety /// # Safety
/// ///
@ -67,6 +76,17 @@ pub unsafe extern "C" fn sp_bit_vec_dealloc(this: *mut BitVec) {
/// Gets the value of a bit from the `BitVec`. /// Gets the value of a bit from the `BitVec`.
/// ///
/// # Arguments
///
/// * `this`: instance to read from
/// * `index`: the bit index to read
///
/// returns: value of the bit
///
/// # Panics
///
/// When accessing `index` out of bounds.
///
/// # Safety /// # Safety
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:
@ -83,6 +103,18 @@ pub unsafe extern "C" fn sp_bit_vec_get(
/// Sets the value of a bit in the `BitVec`. /// Sets the value of a bit in the `BitVec`.
/// ///
/// # Arguments
///
/// * `this`: instance to write to
/// * `index`: the bit index to edit
/// * `value`: the value to set the bit to
///
/// returns: old value of the bit
///
/// # Panics
///
/// When accessing `index` out of bounds.
///
/// # Safety /// # Safety
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:
@ -100,6 +132,10 @@ pub unsafe extern "C" fn sp_bit_vec_set(
/// Sets the value of all bits in the `BitVec`. /// Sets the value of all bits in the `BitVec`.
/// ///
/// # Arguments
///
/// * `value`: the value to set all bits to
///
/// # Safety /// # Safety
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:

View file

@ -3,8 +3,16 @@ use servicepoint::{DataRef, Grid};
use crate::c_slice::CByteSlice; use crate::c_slice::CByteSlice;
/// Creates a new `ByteGrid` instance. /// Creates a new `ByteGrid` with the specified dimensions.
/// The returned instance has to be freed with `byte_grid_dealloc`. ///
/// returns: `ByteGrid` initialized to 0.
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - the returned instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_byte_grid_dealloc`.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_byte_grid_new( pub unsafe extern "C" fn sp_byte_grid_new(
width: usize, width: usize,
@ -14,7 +22,19 @@ pub unsafe extern "C" fn sp_byte_grid_new(
} }
/// Loads a `ByteGrid` with the specified dimensions from the provided data. /// Loads a `ByteGrid` with the specified dimensions from the provided data.
/// The returned instance has to be freed with `byte_grid_dealloc`. ///
/// # Panics
///
/// When the provided `data_length` is not sufficient for the `height` and `width`
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `data` points to a valid memory location of at least `data_length`
/// bytes in size.
/// - the returned instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_byte_grid_dealloc`.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_byte_grid_load( pub unsafe extern "C" fn sp_byte_grid_load(
width: usize, width: usize,
@ -27,7 +47,15 @@ pub unsafe extern "C" fn sp_byte_grid_load(
} }
/// Clones a `ByteGrid`. /// Clones a `ByteGrid`.
/// The returned instance has to be freed with `byte_grid_dealloc`. ///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `this` points to a valid `ByteGrid`
/// - `this` is not written to concurrently
/// - the returned instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_byte_grid_dealloc`.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_byte_grid_clone( pub unsafe extern "C" fn sp_byte_grid_clone(
this: *const ByteGrid, this: *const ByteGrid,
@ -37,13 +65,35 @@ pub unsafe extern "C" fn sp_byte_grid_clone(
/// Deallocates a `ByteGrid`. /// Deallocates a `ByteGrid`.
/// ///
/// Note: do not call this if the grid has been consumed in another way, e.g. to create a command. /// # Safety
///
/// The caller has to make sure that:
///
/// - `this` points to a valid `ByteGrid`
/// - `this` is not used concurrently or after this call
/// - `this` was not passed to another consuming function, e.g. to create a `Command`
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_byte_grid_dealloc(this: *mut ByteGrid) { pub unsafe extern "C" fn sp_byte_grid_dealloc(this: *mut ByteGrid) {
_ = Box::from_raw(this); _ = Box::from_raw(this);
} }
/// Get the current value at the specified position /// Gets the current value at the specified position.
///
/// # Arguments
///
/// * `this`: instance to read from
/// * `x` and `y`: position of the cell to read
///
/// # Panics
///
/// When accessing `x` or `y` out of bounds.
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `this` points to a valid `ByteGrid`
/// - `this` is not written to concurrently
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_byte_grid_get( pub unsafe extern "C" fn sp_byte_grid_get(
this: *const ByteGrid, this: *const ByteGrid,
@ -53,7 +103,26 @@ pub unsafe extern "C" fn sp_byte_grid_get(
(*this).get(x, y) (*this).get(x, y)
} }
/// Sets the current value at the specified position /// Sets the value of the specified position in the `ByteGrid`.
///
/// # Arguments
///
/// * `this`: instance to write to
/// * `x` and `y`: position of the cell
/// * `value`: the value to write to the cell
///
/// returns: old value of the cell
///
/// # Panics
///
/// When accessing `x` or `y` out of bounds.
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `this` points to a valid `BitVec`
/// - `this` is not written to or read from concurrently
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_byte_grid_set( pub unsafe extern "C" fn sp_byte_grid_set(
this: *mut ByteGrid, this: *mut ByteGrid,
@ -64,19 +133,51 @@ pub unsafe extern "C" fn sp_byte_grid_set(
(*this).set(x, y, value); (*this).set(x, y, value);
} }
/// Fills the whole `ByteGrid` with the specified value /// Sets the value of all cells in the `ByteGrid`.
///
/// # Arguments
///
/// * `this`: instance to write to
/// * `value`: the value to set all cells to
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `this` points to a valid `ByteGrid`
/// - `this` is not written to or read from concurrently
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_byte_grid_fill(this: *mut ByteGrid, value: u8) { pub unsafe extern "C" fn sp_byte_grid_fill(this: *mut ByteGrid, value: u8) {
(*this).fill(value); (*this).fill(value);
} }
/// Gets the width in pixels of the `ByteGrid` instance. /// Gets the width in pixels of the `ByteGrid` instance.
///
/// # Arguments
///
/// * `this`: instance to read from
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `this` points to a valid `ByteGrid`
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_byte_grid_width(this: *const ByteGrid) -> usize { pub unsafe extern "C" fn sp_byte_grid_width(this: *const ByteGrid) -> usize {
(*this).width() (*this).width()
} }
/// Gets the height in pixels of the `ByteGrid` instance. /// Gets the height in pixels of the `ByteGrid` instance.
///
/// # Arguments
///
/// * `this`: instance to read from
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `this` points to a valid `ByteGrid`
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_byte_grid_height(this: *const ByteGrid) -> usize { pub unsafe extern "C" fn sp_byte_grid_height(this: *const ByteGrid) -> usize {
(*this).height() (*this).height()
@ -86,11 +187,11 @@ pub unsafe extern "C" fn sp_byte_grid_height(this: *const ByteGrid) -> usize {
/// ///
/// ## Safety /// ## Safety
/// ///
/// The caller has to make sure to never access the returned memory after the `ByteGrid` /// The caller has to make sure that:
/// instance has been consumed or manually deallocated.
/// ///
/// Reading and writing concurrently to either the original instance or the returned data will /// - `this` points to a valid `ByteGrid`
/// result in undefined behavior. /// - the returned memory range is never accessed after the passed `ByteGrid` has been freed
/// - the returned memory range is never accessed concurrently, either via the `ByteGrid` or directly
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_byte_grid_unsafe_data_ref( pub unsafe extern "C" fn sp_byte_grid_unsafe_data_ref(
this: *mut ByteGrid, this: *mut ByteGrid,

View file

@ -1,7 +1,13 @@
#[repr(C)] #[repr(C)]
/// Represents a span of memory (`&mut [u8]` ) as a struct usable by C code. /// Represents a span of memory (`&mut [u8]` ) as a struct usable by C code.
/// ///
/// Usage of this type is inherently unsafe. /// # Safety
///
/// The caller has to make sure that:
///
/// - accesses to the memory pointed to with `start` is never accessed outside `length`
/// - the lifetime of the `CByteSlice` does not outlive the memory it points to, as described in
/// the function returning this type.
pub struct CByteSlice { pub struct CByteSlice {
/// The start address of the memory /// The start address of the memory
pub start: *mut u8, pub start: *mut u8,

View file

@ -1 +1 @@
//! This crate is intentionally left empty. Only the build script is relevant here.