add NULL checks - brightness_grid

This commit is contained in:
Vinzenz Schroeter 2024-10-13 18:22:26 +02:00
parent 03becf19b5
commit bcb73999da
2 changed files with 80 additions and 30 deletions

View file

@ -1,4 +1,4 @@
//! C functions for interacting with `SPBrightnessGrid`s //! C functions for interacting with [SPBrightnessGrid]s
//! //!
//! prefix `sp_brightness_grid_` //! prefix `sp_brightness_grid_`
@ -29,9 +29,9 @@ impl Clone for SPBrightnessGrid {
} }
} }
/// Creates a new `SPBrightnessGrid` with the specified dimensions. /// Creates a new [SPBrightnessGrid] with the specified dimensions.
/// ///
/// returns: `SPBrightnessGrid` initialized to 0. Will never return NULL. /// returns: [SPBrightnessGrid] initialized to 0. Will never return NULL.
/// ///
/// # Safety /// # Safety
/// ///
@ -44,16 +44,21 @@ pub unsafe extern "C" fn sp_brightness_grid_new(
width: usize, width: usize,
height: usize, height: usize,
) -> *mut SPBrightnessGrid { ) -> *mut SPBrightnessGrid {
Box::into_raw(Box::new(SPBrightnessGrid( let result = Box::into_raw(Box::new(SPBrightnessGrid(
servicepoint::BrightnessGrid::new(width, height), servicepoint::BrightnessGrid::new(width, height),
))) )));
assert!(!result.is_null());
result
} }
/// Loads a `SPBrightnessGrid` with the specified dimensions from the provided data. /// Loads a [SPBrightnessGrid] with the specified dimensions from the provided data.
///
/// returns: new [SPBrightnessGrid] instance. Will never return NULL.
/// ///
/// # Panics /// # Panics
/// ///
/// When the provided `data_length` is not sufficient for the `height` and `width` /// - when `data` is NULL
/// - when the provided `data_length` does not match `height` and `width`
/// ///
/// # Safety /// # Safety
/// ///
@ -70,24 +75,33 @@ pub unsafe extern "C" fn sp_brightness_grid_load(
data: *const u8, data: *const u8,
data_length: usize, data_length: usize,
) -> *mut SPBrightnessGrid { ) -> *mut SPBrightnessGrid {
assert!(!data.is_null());
let data = std::slice::from_raw_parts(data, data_length); let data = std::slice::from_raw_parts(data, data_length);
let grid = PrimitiveGrid::load(width, height, data); let grid = PrimitiveGrid::load(width, height, data);
let grid = servicepoint::BrightnessGrid::try_from(grid) let grid = servicepoint::BrightnessGrid::try_from(grid)
.expect("invalid brightness value"); .expect("invalid brightness value");
Box::into_raw(Box::new(SPBrightnessGrid(grid))) let result = Box::into_raw(Box::new(SPBrightnessGrid(grid)));
assert!(!result.is_null());
result
} }
/// Clones a `SPBrightnessGrid`. /// Clones a [SPBrightnessGrid].
/// ///
/// # Arguments /// # Arguments
/// ///
/// - `brightness_grid`: instance to read from /// - `brightness_grid`: instance to read from
/// ///
/// returns: new [SPBrightnessGrid] instance. Will never return NULL.
///
/// # Panics
///
/// - when `brightness_grid` is NULL
///
/// # Safety /// # Safety
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:
/// ///
/// - `brightness_grid` points to a valid `SPBrightnessGrid` /// - `brightness_grid` points to a valid [SPBrightnessGrid]
/// - `brightness_grid` is not written to concurrently /// - `brightness_grid` is not written to concurrently
/// - 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_brightness_grid_free`. /// by explicitly calling `sp_brightness_grid_free`.
@ -95,26 +109,34 @@ pub unsafe extern "C" fn sp_brightness_grid_load(
pub unsafe extern "C" fn sp_brightness_grid_clone( pub unsafe extern "C" fn sp_brightness_grid_clone(
brightness_grid: *const SPBrightnessGrid, brightness_grid: *const SPBrightnessGrid,
) -> *mut SPBrightnessGrid { ) -> *mut SPBrightnessGrid {
Box::into_raw(Box::new((*brightness_grid).clone())) assert!(!brightness_grid.is_null());
let result = Box::into_raw(Box::new((*brightness_grid).clone()));
assert!(!result.is_null());
result
} }
/// Deallocates a `SPBrightnessGrid`. /// Deallocates a [SPBrightnessGrid].
/// ///
/// # Arguments /// # Arguments
/// ///
/// - `brightness_grid`: instance to read from /// - `brightness_grid`: instance to read from
/// ///
/// # Panics
///
/// - when `brightness_grid` is NULL
///
/// # Safety /// # Safety
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:
/// ///
/// - `brightness_grid` points to a valid `SPBrightnessGrid` /// - `brightness_grid` points to a valid [SPBrightnessGrid]
/// - `brightness_grid` is not used concurrently or after this call /// - `brightness_grid` is not used concurrently or after this call
/// - `brightness_grid` was not passed to another consuming function, e.g. to create a [SPCommand] /// - `brightness_grid` was not passed to another consuming function, e.g. to create a [SPCommand]
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_brightness_grid_free( pub unsafe extern "C" fn sp_brightness_grid_free(
brightness_grid: *mut SPBrightnessGrid, brightness_grid: *mut SPBrightnessGrid,
) { ) {
assert!(!brightness_grid.is_null());
_ = Box::from_raw(brightness_grid); _ = Box::from_raw(brightness_grid);
} }
@ -125,15 +147,18 @@ pub unsafe extern "C" fn sp_brightness_grid_free(
/// - `brightness_grid`: instance to read from /// - `brightness_grid`: instance to read from
/// - `x` and `y`: position of the cell to read /// - `x` and `y`: position of the cell to read
/// ///
/// returns: value at position
///
/// # Panics /// # Panics
/// ///
/// When accessing `x` or `y` out of bounds. /// - when `brightness_grid` is NULL
/// - When accessing `x` or `y` out of bounds.
/// ///
/// # Safety /// # Safety
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:
/// ///
/// - `brightness_grid` points to a valid `SPBrightnessGrid` /// - `brightness_grid` points to a valid [SPBrightnessGrid]
/// - `brightness_grid` is not written to concurrently /// - `brightness_grid` is not written to concurrently
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_brightness_grid_get( pub unsafe extern "C" fn sp_brightness_grid_get(
@ -141,10 +166,11 @@ pub unsafe extern "C" fn sp_brightness_grid_get(
x: usize, x: usize,
y: usize, y: usize,
) -> u8 { ) -> u8 {
assert!(!brightness_grid.is_null());
(*brightness_grid).0.get(x, y).into() (*brightness_grid).0.get(x, y).into()
} }
/// Sets the value of the specified position in the `SPBrightnessGrid`. /// Sets the value of the specified position in the [SPBrightnessGrid].
/// ///
/// # Arguments /// # Arguments
/// ///
@ -156,6 +182,7 @@ pub unsafe extern "C" fn sp_brightness_grid_get(
/// ///
/// # Panics /// # Panics
/// ///
/// - when `brightness_grid` is NULL
/// - When accessing `x` or `y` out of bounds. /// - When accessing `x` or `y` out of bounds.
/// - When providing an invalid brightness value /// - When providing an invalid brightness value
/// ///
@ -172,12 +199,13 @@ pub unsafe extern "C" fn sp_brightness_grid_set(
y: usize, y: usize,
value: u8, value: u8,
) { ) {
assert!(!brightness_grid.is_null());
let brightness = let brightness =
Brightness::try_from(value).expect("invalid brightness value"); Brightness::try_from(value).expect("invalid brightness value");
(*brightness_grid).0.set(x, y, brightness); (*brightness_grid).0.set(x, y, brightness);
} }
/// Sets the value of all cells in the `SPBrightnessGrid`. /// Sets the value of all cells in the [SPBrightnessGrid].
/// ///
/// # Arguments /// # Arguments
/// ///
@ -186,79 +214,101 @@ pub unsafe extern "C" fn sp_brightness_grid_set(
/// ///
/// # Panics /// # Panics
/// ///
/// - when `brightness_grid` is NULL
/// - When providing an invalid brightness value /// - When providing an invalid brightness value
/// ///
/// # Safety /// # Safety
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:
/// ///
/// - `brightness_grid` points to a valid `SPBrightnessGrid` /// - `brightness_grid` points to a valid [SPBrightnessGrid]
/// - `brightness_grid` is not written to or read from concurrently /// - `brightness_grid` is not written to or read from concurrently
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_brightness_grid_fill( pub unsafe extern "C" fn sp_brightness_grid_fill(
brightness_grid: *mut SPBrightnessGrid, brightness_grid: *mut SPBrightnessGrid,
value: u8, value: u8,
) { ) {
assert!(!brightness_grid.is_null());
let brightness = let brightness =
Brightness::try_from(value).expect("invalid brightness value"); Brightness::try_from(value).expect("invalid brightness value");
(*brightness_grid).0.fill(brightness); (*brightness_grid).0.fill(brightness);
} }
/// Gets the width of the `SPBrightnessGrid` instance. /// Gets the width of the [SPBrightnessGrid] instance.
/// ///
/// # Arguments /// # Arguments
/// ///
/// - `brightness_grid`: instance to read from /// - `brightness_grid`: instance to read from
/// ///
/// returns: width
///
/// # Panics
///
/// - when `brightness_grid` is NULL
///
/// # Safety /// # Safety
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:
/// ///
/// - `brightness_grid` points to a valid `SPBrightnessGrid` /// - `brightness_grid` points to a valid [SPBrightnessGrid]
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_brightness_grid_width( pub unsafe extern "C" fn sp_brightness_grid_width(
brightness_grid: *const SPBrightnessGrid, brightness_grid: *const SPBrightnessGrid,
) -> usize { ) -> usize {
assert!(!brightness_grid.is_null());
(*brightness_grid).0.width() (*brightness_grid).0.width()
} }
/// Gets the height of the `SPBrightnessGrid` instance. /// Gets the height of the [SPBrightnessGrid] instance.
/// ///
/// # Arguments /// # Arguments
/// ///
/// - `brightness_grid`: instance to read from /// - `brightness_grid`: instance to read from
/// ///
/// returns: height
///
/// # Panics
///
/// - when `brightness_grid` is NULL
///
/// # Safety /// # Safety
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:
/// ///
/// - `brightness_grid` points to a valid `SPBrightnessGrid` /// - `brightness_grid` points to a valid [SPBrightnessGrid]
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_brightness_grid_height( pub unsafe extern "C" fn sp_brightness_grid_height(
brightness_grid: *const SPBrightnessGrid, brightness_grid: *const SPBrightnessGrid,
) -> usize { ) -> usize {
assert!(!brightness_grid.is_null());
(*brightness_grid).0.height() (*brightness_grid).0.height()
} }
/// Gets an unsafe reference to the data of the `SPBrightnessGrid` instance. /// Gets an unsafe reference to the data of the [SPBrightnessGrid] instance.
/// ///
/// # Arguments /// # Arguments
/// ///
/// - `brightness_grid`: instance to read from /// - `brightness_grid`: instance to read from
/// ///
/// ## Safety /// returns: slice of bytes underlying the `brightness_grid`.
///
/// # Panics
///
/// - when `brightness_grid` is NULL
///
/// # Safety
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:
/// ///
/// - `brightness_grid` points to a valid `SPBrightnessGrid` /// - `brightness_grid` points to a valid [SPBrightnessGrid]
/// - the returned memory range is never accessed after the passed `SPBrightnessGrid` has been freed /// - the returned memory range is never accessed after the passed [SPBrightnessGrid] has been freed
/// - the returned memory range is never accessed concurrently, either via the `SPBrightnessGrid` or directly /// - the returned memory range is never accessed concurrently, either via the [SPBrightnessGrid] or directly
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn sp_brightness_grid_unsafe_data_ref( pub unsafe extern "C" fn sp_brightness_grid_unsafe_data_ref(
brightness_grid: *mut SPBrightnessGrid, brightness_grid: *mut SPBrightnessGrid,
) -> SPByteSlice { ) -> SPByteSlice {
assert!(!brightness_grid.is_null());
assert_eq!(core::mem::size_of::<Brightness>(), 1); assert_eq!(core::mem::size_of::<Brightness>(), 1);
let data = (*brightness_grid).0.data_ref_mut(); let data = (*brightness_grid).0.data_ref_mut();
let data: &mut [u8] = transmute(data); let data: &mut [u8] = transmute(data);
SPByteSlice { SPByteSlice {

View file

@ -156,7 +156,7 @@ pub unsafe extern "C" fn sp_command_brightness(
/// Set the brightness of individual tiles in a rectangular area of the display. /// Set the brightness of individual tiles in a rectangular area of the display.
/// ///
/// The passed `SPBrightnessGrid` gets consumed. /// The passed [SPBrightnessGrid] gets consumed.
/// ///
/// Returns: a new `Command::CharBrightness` instance. Will never return NULL. /// Returns: a new `Command::CharBrightness` instance. Will never return NULL.
/// ///
@ -164,7 +164,7 @@ pub unsafe extern "C" fn sp_command_brightness(
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:
/// ///
/// - `grid` points to a valid instance of `SPBrightnessGrid` /// - `grid` points to a valid instance of [SPBrightnessGrid]
/// - `grid` is not used concurrently or after this call /// - `grid` is not used concurrently or after this call
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`. /// by explicitly calling `sp_command_free`.