mirror of
https://github.com/cccb/servicepoint.git
synced 2025-01-18 18:10:14 +01:00
use NonNull as return type in C API
This commit is contained in:
parent
c6450d7759
commit
590b21d433
|
@ -2,6 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! prefix `sp_bitmap_`
|
//! prefix `sp_bitmap_`
|
||||||
|
|
||||||
|
use std::ptr::NonNull;
|
||||||
use servicepoint::{DataRef, Grid};
|
use servicepoint::{DataRef, Grid};
|
||||||
|
|
||||||
use crate::byte_slice::SPByteSlice;
|
use crate::byte_slice::SPByteSlice;
|
||||||
|
@ -41,12 +42,11 @@ pub struct SPBitmap(pub(crate) servicepoint::Bitmap);
|
||||||
pub unsafe extern "C" fn sp_bitmap_new(
|
pub unsafe extern "C" fn sp_bitmap_new(
|
||||||
width: usize,
|
width: usize,
|
||||||
height: usize,
|
height: usize,
|
||||||
) -> *mut SPBitmap {
|
) -> NonNull<SPBitmap> {
|
||||||
let result = Box::into_raw(Box::new(SPBitmap(servicepoint::Bitmap::new(
|
let result = Box::new(SPBitmap(servicepoint::Bitmap::new(
|
||||||
width, height,
|
width, height,
|
||||||
))));
|
)));
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Loads a [SPBitmap] with the specified dimensions from the provided data.
|
/// Loads a [SPBitmap] with the specified dimensions from the provided data.
|
||||||
|
@ -77,14 +77,13 @@ pub unsafe extern "C" fn sp_bitmap_load(
|
||||||
height: usize,
|
height: usize,
|
||||||
data: *const u8,
|
data: *const u8,
|
||||||
data_length: usize,
|
data_length: usize,
|
||||||
) -> *mut SPBitmap {
|
) -> NonNull<SPBitmap> {
|
||||||
assert!(!data.is_null());
|
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 result = Box::into_raw(Box::new(SPBitmap(servicepoint::Bitmap::load(
|
let result = Box::new(SPBitmap(servicepoint::Bitmap::load(
|
||||||
width, height, data,
|
width, height, data,
|
||||||
))));
|
)));
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clones a [SPBitmap].
|
/// Clones a [SPBitmap].
|
||||||
|
@ -106,11 +105,10 @@ pub unsafe extern "C" fn sp_bitmap_load(
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn sp_bitmap_clone(
|
pub unsafe extern "C" fn sp_bitmap_clone(
|
||||||
bitmap: *const SPBitmap,
|
bitmap: *const SPBitmap,
|
||||||
) -> *mut SPBitmap {
|
) -> NonNull<SPBitmap> {
|
||||||
assert!(!bitmap.is_null());
|
assert!(!bitmap.is_null());
|
||||||
let result = Box::into_raw(Box::new(SPBitmap((*bitmap).0.clone())));
|
let result = Box::new(SPBitmap((*bitmap).0.clone()));
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deallocates a [SPBitmap].
|
/// Deallocates a [SPBitmap].
|
||||||
|
@ -277,7 +275,7 @@ pub unsafe extern "C" fn sp_bitmap_unsafe_data_ref(
|
||||||
assert!(!bitmap.is_null());
|
assert!(!bitmap.is_null());
|
||||||
let data = (*bitmap).0.data_ref_mut();
|
let data = (*bitmap).0.data_ref_mut();
|
||||||
SPByteSlice {
|
SPByteSlice {
|
||||||
start: data.as_mut_ptr_range().start,
|
start: NonNull::new(data.as_mut_ptr_range().start).unwrap(),
|
||||||
length: data.len(),
|
length: data.len(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! prefix `sp_bitvec_`
|
//! prefix `sp_bitvec_`
|
||||||
|
|
||||||
|
use std::ptr::NonNull;
|
||||||
use crate::SPByteSlice;
|
use crate::SPByteSlice;
|
||||||
use servicepoint::bitvec::prelude::{BitVec, Msb0};
|
use servicepoint::bitvec::prelude::{BitVec, Msb0};
|
||||||
|
|
||||||
|
@ -52,10 +53,9 @@ impl Clone for SPBitVec {
|
||||||
/// - 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_bitvec_free`.
|
/// by explicitly calling `sp_bitvec_free`.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn sp_bitvec_new(size: usize) -> *mut SPBitVec {
|
pub unsafe extern "C" fn sp_bitvec_new(size: usize) -> NonNull<SPBitVec> {
|
||||||
let result = Box::into_raw(Box::new(SPBitVec(BitVec::repeat(false, size))));
|
let result = Box::new(SPBitVec(BitVec::repeat(false, size)));
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Interpret the data as a series of bits and load then into a new [SPBitVec] instance.
|
/// Interpret the data as a series of bits and load then into a new [SPBitVec] instance.
|
||||||
|
@ -78,12 +78,11 @@ pub unsafe extern "C" fn sp_bitvec_new(size: usize) -> *mut SPBitVec {
|
||||||
pub unsafe extern "C" fn sp_bitvec_load(
|
pub unsafe extern "C" fn sp_bitvec_load(
|
||||||
data: *const u8,
|
data: *const u8,
|
||||||
data_length: usize,
|
data_length: usize,
|
||||||
) -> *mut SPBitVec {
|
) -> NonNull<SPBitVec> {
|
||||||
assert!(!data.is_null());
|
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 result = Box::into_raw(Box::new(SPBitVec(BitVec::from_slice(data))));
|
let result = Box::new(SPBitVec(BitVec::from_slice(data)));
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clones a [SPBitVec].
|
/// Clones a [SPBitVec].
|
||||||
|
@ -105,11 +104,10 @@ pub unsafe extern "C" fn sp_bitvec_load(
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn sp_bitvec_clone(
|
pub unsafe extern "C" fn sp_bitvec_clone(
|
||||||
bit_vec: *const SPBitVec,
|
bit_vec: *const SPBitVec,
|
||||||
) -> *mut SPBitVec {
|
) -> NonNull<SPBitVec> {
|
||||||
assert!(!bit_vec.is_null());
|
assert!(!bit_vec.is_null());
|
||||||
let result = Box::into_raw(Box::new((*bit_vec).clone()));
|
let result = Box::new((*bit_vec).clone());
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deallocates a [SPBitVec].
|
/// Deallocates a [SPBitVec].
|
||||||
|
@ -278,7 +276,7 @@ pub unsafe extern "C" fn sp_bitvec_unsafe_data_ref(
|
||||||
assert!(!bit_vec.is_null());
|
assert!(!bit_vec.is_null());
|
||||||
let data = (*bit_vec).0.as_raw_mut_slice();
|
let data = (*bit_vec).0.as_raw_mut_slice();
|
||||||
SPByteSlice {
|
SPByteSlice {
|
||||||
start: data.as_mut_ptr_range().start,
|
start: NonNull::new(data.as_mut_ptr_range().start).unwrap(),
|
||||||
length: data.len(),
|
length: data.len(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
use crate::SPByteSlice;
|
use crate::SPByteSlice;
|
||||||
use servicepoint::{Brightness, DataRef, Grid, PrimitiveGrid};
|
use servicepoint::{Brightness, DataRef, Grid, PrimitiveGrid};
|
||||||
use std::intrinsics::transmute;
|
use std::intrinsics::transmute;
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
/// A grid containing brightness values.
|
/// A grid containing brightness values.
|
||||||
///
|
///
|
||||||
|
@ -38,12 +39,11 @@ pub struct SPBrightnessGrid(pub(crate) servicepoint::BrightnessGrid);
|
||||||
pub unsafe extern "C" fn sp_brightness_grid_new(
|
pub unsafe extern "C" fn sp_brightness_grid_new(
|
||||||
width: usize,
|
width: usize,
|
||||||
height: usize,
|
height: usize,
|
||||||
) -> *mut SPBrightnessGrid {
|
) -> NonNull<SPBrightnessGrid> {
|
||||||
let result = Box::into_raw(Box::new(SPBrightnessGrid(
|
let result = Box::new(SPBrightnessGrid(
|
||||||
servicepoint::BrightnessGrid::new(width, height),
|
servicepoint::BrightnessGrid::new(width, height),
|
||||||
)));
|
));
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Loads a [SPBrightnessGrid] with the specified dimensions from the provided data.
|
/// Loads a [SPBrightnessGrid] with the specified dimensions from the provided data.
|
||||||
|
@ -69,15 +69,14 @@ pub unsafe extern "C" fn sp_brightness_grid_load(
|
||||||
height: usize,
|
height: usize,
|
||||||
data: *const u8,
|
data: *const u8,
|
||||||
data_length: usize,
|
data_length: usize,
|
||||||
) -> *mut SPBrightnessGrid {
|
) -> NonNull<SPBrightnessGrid> {
|
||||||
assert!(!data.is_null());
|
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");
|
||||||
let result = Box::into_raw(Box::new(SPBrightnessGrid(grid)));
|
let result = Box::new(SPBrightnessGrid(grid));
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clones a [SPBrightnessGrid].
|
/// Clones a [SPBrightnessGrid].
|
||||||
|
@ -103,11 +102,10 @@ pub unsafe extern "C" fn sp_brightness_grid_load(
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
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 {
|
) -> NonNull<SPBrightnessGrid> {
|
||||||
assert!(!brightness_grid.is_null());
|
assert!(!brightness_grid.is_null());
|
||||||
let result = Box::into_raw(Box::new((*brightness_grid).clone()));
|
let result = Box::new((*brightness_grid).clone());
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deallocates a [SPBrightnessGrid].
|
/// Deallocates a [SPBrightnessGrid].
|
||||||
|
@ -305,9 +303,10 @@ pub unsafe extern "C" fn sp_brightness_grid_unsafe_data_ref(
|
||||||
assert!(!brightness_grid.is_null());
|
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();
|
||||||
|
// this assumes more about the memory layout than rust guarantees. yikes!
|
||||||
let data: &mut [u8] = transmute(data);
|
let data: &mut [u8] = transmute(data);
|
||||||
SPByteSlice {
|
SPByteSlice {
|
||||||
start: data.as_mut_ptr_range().start,
|
start: NonNull::new(data.as_mut_ptr_range().start).unwrap(),
|
||||||
length: data.len(),
|
length: data.len(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
//! FFI slice helper
|
//! FFI slice helper
|
||||||
|
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
#[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.
|
||||||
///
|
///
|
||||||
|
@ -16,7 +18,7 @@
|
||||||
/// will try to free the memory of a potentially separate allocator.
|
/// will try to free the memory of a potentially separate allocator.
|
||||||
pub struct SPByteSlice {
|
pub struct SPByteSlice {
|
||||||
/// The start address of the memory
|
/// The start address of the memory
|
||||||
pub start: *mut u8,
|
pub start: NonNull<u8>,
|
||||||
/// The amount of memory in bytes
|
/// The amount of memory in bytes
|
||||||
pub length: usize,
|
pub length: usize,
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! prefix `sp_command_`
|
//! prefix `sp_command_`
|
||||||
|
|
||||||
use std::ptr::null_mut;
|
use std::ptr::{null_mut, NonNull};
|
||||||
|
|
||||||
use servicepoint::{Brightness, Origin};
|
use servicepoint::{Brightness, Origin};
|
||||||
|
|
||||||
|
@ -80,11 +80,10 @@ pub unsafe extern "C" fn sp_command_try_from_packet(
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn sp_command_clone(
|
pub unsafe extern "C" fn sp_command_clone(
|
||||||
command: *const SPCommand,
|
command: *const SPCommand,
|
||||||
) -> *mut SPCommand {
|
) -> NonNull<SPCommand> {
|
||||||
assert!(!command.is_null());
|
assert!(!command.is_null());
|
||||||
let result = Box::into_raw(Box::new((*command).clone()));
|
let result = Box::new((*command).clone());
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set all pixels to the off state.
|
/// Set all pixels to the off state.
|
||||||
|
@ -106,11 +105,9 @@ pub unsafe extern "C" fn sp_command_clone(
|
||||||
/// - 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`.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn sp_command_clear() -> *mut SPCommand {
|
pub unsafe extern "C" fn sp_command_clear() -> NonNull<SPCommand> {
|
||||||
let result =
|
let result = Box::new(SPCommand(servicepoint::Command::Clear));
|
||||||
Box::into_raw(Box::new(SPCommand(servicepoint::Command::Clear)));
|
NonNull::from(Box::leak(result))
|
||||||
assert!(!result.is_null());
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Kills the udp daemon on the display, which usually results in a restart.
|
/// Kills the udp daemon on the display, which usually results in a restart.
|
||||||
|
@ -126,11 +123,9 @@ pub unsafe extern "C" fn sp_command_clear() -> *mut SPCommand {
|
||||||
/// - 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`.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn sp_command_hard_reset() -> *mut SPCommand {
|
pub unsafe extern "C" fn sp_command_hard_reset() -> NonNull<SPCommand> {
|
||||||
let result =
|
let result = Box::new(SPCommand(servicepoint::Command::HardReset));
|
||||||
Box::into_raw(Box::new(SPCommand(servicepoint::Command::HardReset)));
|
NonNull::from(Box::leak(result))
|
||||||
assert!(!result.is_null());
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A yet-to-be-tested command.
|
/// A yet-to-be-tested command.
|
||||||
|
@ -144,11 +139,9 @@ pub unsafe extern "C" fn sp_command_hard_reset() -> *mut SPCommand {
|
||||||
/// - 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`.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn sp_command_fade_out() -> *mut SPCommand {
|
pub unsafe extern "C" fn sp_command_fade_out() -> NonNull<SPCommand> {
|
||||||
let result =
|
let result = Box::new(SPCommand(servicepoint::Command::FadeOut));
|
||||||
Box::into_raw(Box::new(SPCommand(servicepoint::Command::FadeOut)));
|
NonNull::from(Box::leak(result))
|
||||||
assert!(!result.is_null());
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the brightness of all tiles to the same value.
|
/// Set the brightness of all tiles to the same value.
|
||||||
|
@ -168,14 +161,13 @@ pub unsafe extern "C" fn sp_command_fade_out() -> *mut SPCommand {
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn sp_command_brightness(
|
pub unsafe extern "C" fn sp_command_brightness(
|
||||||
brightness: u8,
|
brightness: u8,
|
||||||
) -> *mut SPCommand {
|
) -> NonNull<SPCommand> {
|
||||||
let brightness =
|
let brightness =
|
||||||
Brightness::try_from(brightness).expect("invalid brightness");
|
Brightness::try_from(brightness).expect("invalid brightness");
|
||||||
let result = Box::into_raw(Box::new(SPCommand(
|
let result = Box::new(SPCommand(
|
||||||
servicepoint::Command::Brightness(brightness),
|
servicepoint::Command::Brightness(brightness),
|
||||||
)));
|
));
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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.
|
||||||
|
@ -201,14 +193,13 @@ pub unsafe extern "C" fn sp_command_char_brightness(
|
||||||
x: usize,
|
x: usize,
|
||||||
y: usize,
|
y: usize,
|
||||||
grid: *mut SPBrightnessGrid,
|
grid: *mut SPBrightnessGrid,
|
||||||
) -> *mut SPCommand {
|
) -> NonNull<SPCommand> {
|
||||||
assert!(!grid.is_null());
|
assert!(!grid.is_null());
|
||||||
let byte_grid = *Box::from_raw(grid);
|
let byte_grid = *Box::from_raw(grid);
|
||||||
let result = Box::into_raw(Box::new(SPCommand(
|
let result = Box::new(SPCommand(
|
||||||
servicepoint::Command::CharBrightness(Origin::new(x, y), byte_grid.0),
|
servicepoint::Command::CharBrightness(Origin::new(x, y), byte_grid.0),
|
||||||
)));
|
));
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set pixel data starting at the pixel offset on screen.
|
/// Set pixel data starting at the pixel offset on screen.
|
||||||
|
@ -241,18 +232,17 @@ pub unsafe extern "C" fn sp_command_bitmap_linear(
|
||||||
offset: usize,
|
offset: usize,
|
||||||
bit_vec: *mut SPBitVec,
|
bit_vec: *mut SPBitVec,
|
||||||
compression: SPCompressionCode,
|
compression: SPCompressionCode,
|
||||||
) -> *mut SPCommand {
|
) -> NonNull<SPCommand> {
|
||||||
assert!(!bit_vec.is_null());
|
assert!(!bit_vec.is_null());
|
||||||
let bit_vec = *Box::from_raw(bit_vec);
|
let bit_vec = *Box::from_raw(bit_vec);
|
||||||
let result = Box::into_raw(Box::new(SPCommand(
|
let result = Box::new(SPCommand(
|
||||||
servicepoint::Command::BitmapLinear(
|
servicepoint::Command::BitmapLinear(
|
||||||
offset,
|
offset,
|
||||||
bit_vec.into(),
|
bit_vec.into(),
|
||||||
compression.try_into().expect("invalid compression code"),
|
compression.try_into().expect("invalid compression code"),
|
||||||
),
|
),
|
||||||
)));
|
));
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set pixel data according to an and-mask starting at the offset.
|
/// Set pixel data according to an and-mask starting at the offset.
|
||||||
|
@ -285,18 +275,17 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_and(
|
||||||
offset: usize,
|
offset: usize,
|
||||||
bit_vec: *mut SPBitVec,
|
bit_vec: *mut SPBitVec,
|
||||||
compression: SPCompressionCode,
|
compression: SPCompressionCode,
|
||||||
) -> *mut SPCommand {
|
) -> NonNull<SPCommand> {
|
||||||
assert!(!bit_vec.is_null());
|
assert!(!bit_vec.is_null());
|
||||||
let bit_vec = *Box::from_raw(bit_vec);
|
let bit_vec = *Box::from_raw(bit_vec);
|
||||||
let result = Box::into_raw(Box::new(SPCommand(
|
let result = Box::new(SPCommand(
|
||||||
servicepoint::Command::BitmapLinearAnd(
|
servicepoint::Command::BitmapLinearAnd(
|
||||||
offset,
|
offset,
|
||||||
bit_vec.into(),
|
bit_vec.into(),
|
||||||
compression.try_into().expect("invalid compression code"),
|
compression.try_into().expect("invalid compression code"),
|
||||||
),
|
),
|
||||||
)));
|
));
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set pixel data according to an or-mask starting at the offset.
|
/// Set pixel data according to an or-mask starting at the offset.
|
||||||
|
@ -329,18 +318,17 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_or(
|
||||||
offset: usize,
|
offset: usize,
|
||||||
bit_vec: *mut SPBitVec,
|
bit_vec: *mut SPBitVec,
|
||||||
compression: SPCompressionCode,
|
compression: SPCompressionCode,
|
||||||
) -> *mut SPCommand {
|
) -> NonNull<SPCommand> {
|
||||||
assert!(!bit_vec.is_null());
|
assert!(!bit_vec.is_null());
|
||||||
let bit_vec = *Box::from_raw(bit_vec);
|
let bit_vec = *Box::from_raw(bit_vec);
|
||||||
let result = Box::into_raw(Box::new(SPCommand(
|
let result = Box::new(SPCommand(
|
||||||
servicepoint::Command::BitmapLinearOr(
|
servicepoint::Command::BitmapLinearOr(
|
||||||
offset,
|
offset,
|
||||||
bit_vec.into(),
|
bit_vec.into(),
|
||||||
compression.try_into().expect("invalid compression code"),
|
compression.try_into().expect("invalid compression code"),
|
||||||
),
|
),
|
||||||
)));
|
));
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set pixel data according to a xor-mask starting at the offset.
|
/// Set pixel data according to a xor-mask starting at the offset.
|
||||||
|
@ -373,18 +361,17 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_xor(
|
||||||
offset: usize,
|
offset: usize,
|
||||||
bit_vec: *mut SPBitVec,
|
bit_vec: *mut SPBitVec,
|
||||||
compression: SPCompressionCode,
|
compression: SPCompressionCode,
|
||||||
) -> *mut SPCommand {
|
) -> NonNull<SPCommand> {
|
||||||
assert!(!bit_vec.is_null());
|
assert!(!bit_vec.is_null());
|
||||||
let bit_vec = *Box::from_raw(bit_vec);
|
let bit_vec = *Box::from_raw(bit_vec);
|
||||||
let result = Box::into_raw(Box::new(SPCommand(
|
let result = Box::new(SPCommand(
|
||||||
servicepoint::Command::BitmapLinearXor(
|
servicepoint::Command::BitmapLinearXor(
|
||||||
offset,
|
offset,
|
||||||
bit_vec.into(),
|
bit_vec.into(),
|
||||||
compression.try_into().expect("invalid compression code"),
|
compression.try_into().expect("invalid compression code"),
|
||||||
),
|
),
|
||||||
)));
|
));
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show text on the screen.
|
/// Show text on the screen.
|
||||||
|
@ -410,14 +397,13 @@ pub unsafe extern "C" fn sp_command_cp437_data(
|
||||||
x: usize,
|
x: usize,
|
||||||
y: usize,
|
y: usize,
|
||||||
grid: *mut SPCp437Grid,
|
grid: *mut SPCp437Grid,
|
||||||
) -> *mut SPCommand {
|
) -> NonNull<SPCommand> {
|
||||||
assert!(!grid.is_null());
|
assert!(!grid.is_null());
|
||||||
let grid = *Box::from_raw(grid);
|
let grid = *Box::from_raw(grid);
|
||||||
let result = Box::into_raw(Box::new(SPCommand(
|
let result = Box::new(SPCommand(
|
||||||
servicepoint::Command::Cp437Data(Origin::new(x, y), grid.0),
|
servicepoint::Command::Cp437Data(Origin::new(x, y), grid.0),
|
||||||
)));
|
));
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets a window of pixels to the specified values.
|
/// Sets a window of pixels to the specified values.
|
||||||
|
@ -446,10 +432,10 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_win(
|
||||||
y: usize,
|
y: usize,
|
||||||
bitmap: *mut SPBitmap,
|
bitmap: *mut SPBitmap,
|
||||||
compression_code: SPCompressionCode,
|
compression_code: SPCompressionCode,
|
||||||
) -> *mut SPCommand {
|
) -> NonNull<SPCommand> {
|
||||||
assert!(!bitmap.is_null());
|
assert!(!bitmap.is_null());
|
||||||
let byte_grid = (*Box::from_raw(bitmap)).0;
|
let byte_grid = (*Box::from_raw(bitmap)).0;
|
||||||
let result = Box::into_raw(Box::new(SPCommand(
|
let result = Box::new(SPCommand(
|
||||||
servicepoint::Command::BitmapLinearWin(
|
servicepoint::Command::BitmapLinearWin(
|
||||||
Origin::new(x, y),
|
Origin::new(x, y),
|
||||||
byte_grid,
|
byte_grid,
|
||||||
|
@ -457,9 +443,8 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_win(
|
||||||
.try_into()
|
.try_into()
|
||||||
.expect("invalid compression code"),
|
.expect("invalid compression code"),
|
||||||
),
|
),
|
||||||
)));
|
));
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deallocates a [SPCommand].
|
/// Deallocates a [SPCommand].
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! prefix `sp_cp437_grid_`
|
//! prefix `sp_cp437_grid_`
|
||||||
|
|
||||||
|
use std::ptr::NonNull;
|
||||||
use crate::SPByteSlice;
|
use crate::SPByteSlice;
|
||||||
use servicepoint::{DataRef, Grid};
|
use servicepoint::{DataRef, Grid};
|
||||||
|
|
||||||
|
@ -39,12 +40,11 @@ impl Clone for SPCp437Grid {
|
||||||
pub unsafe extern "C" fn sp_cp437_grid_new(
|
pub unsafe extern "C" fn sp_cp437_grid_new(
|
||||||
width: usize,
|
width: usize,
|
||||||
height: usize,
|
height: usize,
|
||||||
) -> *mut SPCp437Grid {
|
) -> NonNull<SPCp437Grid> {
|
||||||
let result = Box::into_raw(Box::new(SPCp437Grid(
|
let result = Box::new(SPCp437Grid(
|
||||||
servicepoint::Cp437Grid::new(width, height),
|
servicepoint::Cp437Grid::new(width, height),
|
||||||
)));
|
));
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Loads a [SPCp437Grid] with the specified dimensions from the provided data.
|
/// Loads a [SPCp437Grid] with the specified dimensions from the provided data.
|
||||||
|
@ -70,14 +70,13 @@ pub unsafe extern "C" fn sp_cp437_grid_load(
|
||||||
height: usize,
|
height: usize,
|
||||||
data: *const u8,
|
data: *const u8,
|
||||||
data_length: usize,
|
data_length: usize,
|
||||||
) -> *mut SPCp437Grid {
|
) -> NonNull<SPCp437Grid> {
|
||||||
assert!(data.is_null());
|
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 result = Box::into_raw(Box::new(SPCp437Grid(
|
let result = Box::new(SPCp437Grid(
|
||||||
servicepoint::Cp437Grid::load(width, height, data),
|
servicepoint::Cp437Grid::load(width, height, data),
|
||||||
)));
|
));
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clones a [SPCp437Grid].
|
/// Clones a [SPCp437Grid].
|
||||||
|
@ -99,11 +98,10 @@ pub unsafe extern "C" fn sp_cp437_grid_load(
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn sp_cp437_grid_clone(
|
pub unsafe extern "C" fn sp_cp437_grid_clone(
|
||||||
cp437_grid: *const SPCp437Grid,
|
cp437_grid: *const SPCp437Grid,
|
||||||
) -> *mut SPCp437Grid {
|
) -> NonNull<SPCp437Grid> {
|
||||||
assert!(!cp437_grid.is_null());
|
assert!(!cp437_grid.is_null());
|
||||||
let result = Box::into_raw(Box::new((*cp437_grid).clone()));
|
let result = Box::new((*cp437_grid).clone());
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deallocates a [SPCp437Grid].
|
/// Deallocates a [SPCp437Grid].
|
||||||
|
@ -278,7 +276,7 @@ pub unsafe extern "C" fn sp_cp437_grid_unsafe_data_ref(
|
||||||
) -> SPByteSlice {
|
) -> SPByteSlice {
|
||||||
let data = (*cp437_grid).0.data_ref_mut();
|
let data = (*cp437_grid).0.data_ref_mut();
|
||||||
SPByteSlice {
|
SPByteSlice {
|
||||||
start: data.as_mut_ptr_range().start,
|
start: NonNull::new(data.as_mut_ptr_range().start).unwrap(),
|
||||||
length: data.len(),
|
length: data.len(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! prefix `sp_packet_`
|
//! prefix `sp_packet_`
|
||||||
|
|
||||||
use std::ptr::null_mut;
|
use std::ptr::{null_mut, NonNull};
|
||||||
|
|
||||||
use crate::SPCommand;
|
use crate::SPCommand;
|
||||||
|
|
||||||
|
@ -29,13 +29,11 @@ pub struct SPPacket(pub(crate) servicepoint::packet::Packet);
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn sp_packet_from_command(
|
pub unsafe extern "C" fn sp_packet_from_command(
|
||||||
command: *mut SPCommand,
|
command: *mut SPCommand,
|
||||||
) -> *mut SPPacket {
|
) -> NonNull<SPPacket> {
|
||||||
assert!(!command.is_null());
|
assert!(!command.is_null());
|
||||||
let command = *Box::from_raw(command);
|
let command = *Box::from_raw(command);
|
||||||
let packet = SPPacket(command.0.into());
|
let result = Box::new(SPPacket(command.0.into()));
|
||||||
let result = Box::into_raw(Box::new(packet));
|
NonNull::from(Box::leak(result))
|
||||||
assert!(!result.is_null());
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tries to load a [SPPacket] from the passed array with the specified length.
|
/// Tries to load a [SPPacket] from the passed array with the specified length.
|
||||||
|
@ -86,11 +84,10 @@ pub unsafe extern "C" fn sp_packet_try_load(
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn sp_packet_clone(
|
pub unsafe extern "C" fn sp_packet_clone(
|
||||||
packet: *const SPPacket,
|
packet: *const SPPacket,
|
||||||
) -> *mut SPPacket {
|
) -> NonNull<SPPacket> {
|
||||||
assert!(!packet.is_null());
|
assert!(!packet.is_null());
|
||||||
let result = Box::into_raw(Box::new(SPPacket((*packet).0.clone())));
|
let result = Box::new(SPPacket((*packet).0.clone()));
|
||||||
assert!(!result.is_null());
|
NonNull::from(Box::leak(result))
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deallocates a [SPPacket].
|
/// Deallocates a [SPPacket].
|
||||||
|
|
Loading…
Reference in a new issue