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_`
@ -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
///
@ -44,16 +44,21 @@ pub unsafe extern "C" fn sp_brightness_grid_new(
width: usize,
height: usize,
) -> *mut SPBrightnessGrid {
Box::into_raw(Box::new(SPBrightnessGrid(
let result = Box::into_raw(Box::new(SPBrightnessGrid(
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
///
/// 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
///
@ -70,24 +75,33 @@ pub unsafe extern "C" fn sp_brightness_grid_load(
data: *const u8,
data_length: usize,
) -> *mut SPBrightnessGrid {
assert!(!data.is_null());
let data = std::slice::from_raw_parts(data, data_length);
let grid = PrimitiveGrid::load(width, height, data);
let grid = servicepoint::BrightnessGrid::try_from(grid)
.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
///
/// - `brightness_grid`: instance to read from
///
/// returns: new [SPBrightnessGrid] instance. Will never return NULL.
///
/// # Panics
///
/// - when `brightness_grid` is NULL
///
/// # Safety
///
/// 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
/// - the returned instance is freed in some way, either by using a consuming function or
/// 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(
brightness_grid: *const 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
///
/// - `brightness_grid`: instance to read from
///
/// # Panics
///
/// - when `brightness_grid` is NULL
///
/// # Safety
///
/// 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` was not passed to another consuming function, e.g. to create a [SPCommand]
#[no_mangle]
pub unsafe extern "C" fn sp_brightness_grid_free(
brightness_grid: *mut SPBrightnessGrid,
) {
assert!(!brightness_grid.is_null());
_ = Box::from_raw(brightness_grid);
}
@ -125,15 +147,18 @@ pub unsafe extern "C" fn sp_brightness_grid_free(
/// - `brightness_grid`: instance to read from
/// - `x` and `y`: position of the cell to read
///
/// returns: value at position
///
/// # Panics
///
/// When accessing `x` or `y` out of bounds.
/// - when `brightness_grid` is NULL
/// - When accessing `x` or `y` out of bounds.
///
/// # Safety
///
/// 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
#[no_mangle]
pub unsafe extern "C" fn sp_brightness_grid_get(
@ -141,10 +166,11 @@ pub unsafe extern "C" fn sp_brightness_grid_get(
x: usize,
y: usize,
) -> u8 {
assert!(!brightness_grid.is_null());
(*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
///
@ -156,6 +182,7 @@ pub unsafe extern "C" fn sp_brightness_grid_get(
///
/// # Panics
///
/// - when `brightness_grid` is NULL
/// - When accessing `x` or `y` out of bounds.
/// - When providing an invalid brightness value
///
@ -172,12 +199,13 @@ pub unsafe extern "C" fn sp_brightness_grid_set(
y: usize,
value: u8,
) {
assert!(!brightness_grid.is_null());
let brightness =
Brightness::try_from(value).expect("invalid brightness value");
(*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
///
@ -186,79 +214,101 @@ pub unsafe extern "C" fn sp_brightness_grid_set(
///
/// # Panics
///
/// - when `brightness_grid` is NULL
/// - When providing an invalid brightness value
///
/// # Safety
///
/// 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
#[no_mangle]
pub unsafe extern "C" fn sp_brightness_grid_fill(
brightness_grid: *mut SPBrightnessGrid,
value: u8,
) {
assert!(!brightness_grid.is_null());
let brightness =
Brightness::try_from(value).expect("invalid brightness value");
(*brightness_grid).0.fill(brightness);
}
/// Gets the width of the `SPBrightnessGrid` instance.
/// Gets the width of the [SPBrightnessGrid] instance.
///
/// # Arguments
///
/// - `brightness_grid`: instance to read from
///
/// returns: width
///
/// # Panics
///
/// - when `brightness_grid` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `brightness_grid` points to a valid `SPBrightnessGrid`
/// - `brightness_grid` points to a valid [SPBrightnessGrid]
#[no_mangle]
pub unsafe extern "C" fn sp_brightness_grid_width(
brightness_grid: *const SPBrightnessGrid,
) -> usize {
assert!(!brightness_grid.is_null());
(*brightness_grid).0.width()
}
/// Gets the height of the `SPBrightnessGrid` instance.
/// Gets the height of the [SPBrightnessGrid] instance.
///
/// # Arguments
///
/// - `brightness_grid`: instance to read from
///
/// returns: height
///
/// # Panics
///
/// - when `brightness_grid` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `brightness_grid` points to a valid `SPBrightnessGrid`
/// - `brightness_grid` points to a valid [SPBrightnessGrid]
#[no_mangle]
pub unsafe extern "C" fn sp_brightness_grid_height(
brightness_grid: *const SPBrightnessGrid,
) -> usize {
assert!(!brightness_grid.is_null());
(*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
///
/// - `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:
///
/// - `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 concurrently, either via the `SPBrightnessGrid` or directly
/// - `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 concurrently, either via the [SPBrightnessGrid] or directly
#[no_mangle]
pub unsafe extern "C" fn sp_brightness_grid_unsafe_data_ref(
brightness_grid: *mut SPBrightnessGrid,
) -> SPByteSlice {
assert!(!brightness_grid.is_null());
assert_eq!(core::mem::size_of::<Brightness>(), 1);
let data = (*brightness_grid).0.data_ref_mut();
let data: &mut [u8] = transmute(data);
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.
///
/// The passed `SPBrightnessGrid` gets consumed.
/// The passed [SPBrightnessGrid] gets consumed.
///
/// 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:
///
/// - `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
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.