functions for manipulating packets

This commit is contained in:
Vinzenz Schroeter 2025-04-12 12:05:19 +02:00
parent 1a58294f88
commit d215f7199e
9 changed files with 81 additions and 37 deletions

View file

@ -18,7 +18,6 @@ use std::ptr::NonNull;
use crate::byte_slice::SPByteSlice;
/// Creates a new [SPBitmap] with the specified dimensions.
///
/// # Arguments
@ -63,7 +62,8 @@ pub unsafe extern "C" fn sp_bitmap_new(
/// - the returned instance is freed in some way, either by using a consuming function or
/// by explicitly calling [sp_bitmap_free].
#[no_mangle]
pub unsafe extern "C" fn sp_bitmap_new_screen_sized() -> NonNull<servicepoint::Bitmap> {
pub unsafe extern "C" fn sp_bitmap_new_screen_sized(
) -> NonNull<servicepoint::Bitmap> {
let result = Box::new(servicepoint::Bitmap::max_sized());
NonNull::from(Box::leak(result))
}
@ -235,7 +235,10 @@ pub unsafe extern "C" fn sp_bitmap_set(
/// - `bitmap` points to a valid [SPBitmap]
/// - `bitmap` is not written to or read from concurrently
#[no_mangle]
pub unsafe extern "C" fn sp_bitmap_fill(bitmap: *mut servicepoint::Bitmap, value: bool) {
pub unsafe extern "C" fn sp_bitmap_fill(
bitmap: *mut servicepoint::Bitmap,
value: bool,
) {
assert!(!bitmap.is_null());
unsafe { (*bitmap).fill(value) };
}
@ -256,7 +259,9 @@ pub unsafe extern "C" fn sp_bitmap_fill(bitmap: *mut servicepoint::Bitmap, value
///
/// - `bitmap` points to a valid [SPBitmap]
#[no_mangle]
pub unsafe extern "C" fn sp_bitmap_width(bitmap: *const servicepoint::Bitmap) -> usize {
pub unsafe extern "C" fn sp_bitmap_width(
bitmap: *const servicepoint::Bitmap,
) -> usize {
assert!(!bitmap.is_null());
unsafe { (*bitmap).width() }
}
@ -277,7 +282,9 @@ pub unsafe extern "C" fn sp_bitmap_width(bitmap: *const servicepoint::Bitmap) ->
///
/// - `bitmap` points to a valid [SPBitmap]
#[no_mangle]
pub unsafe extern "C" fn sp_bitmap_height(bitmap: *const servicepoint::Bitmap) -> usize {
pub unsafe extern "C" fn sp_bitmap_height(
bitmap: *const servicepoint::Bitmap,
) -> usize {
assert!(!bitmap.is_null());
unsafe { (*bitmap).height() }
}
@ -300,9 +307,5 @@ pub unsafe extern "C" fn sp_bitmap_unsafe_data_ref(
bitmap: *mut servicepoint::Bitmap,
) -> SPByteSlice {
assert!(!bitmap.is_null());
let data = unsafe { (*bitmap).data_ref_mut() };
SPByteSlice {
start: NonNull::new(data.as_mut_ptr_range().start).unwrap(),
length: data.len(),
}
unsafe { SPByteSlice::from_slice((*bitmap).data_ref_mut()) }
}

View file

@ -275,9 +275,5 @@ pub unsafe extern "C" fn sp_bitvec_unsafe_data_ref(
bit_vec: *mut SPBitVec,
) -> SPByteSlice {
assert!(!bit_vec.is_null());
let data = unsafe { (*bit_vec).0.as_raw_mut_slice() };
SPByteSlice {
start: NonNull::new(data.as_mut_ptr_range().start).unwrap(),
length: data.len(),
}
unsafe { SPByteSlice::from_slice((*bit_vec).0.as_raw_mut_slice() ) }
}

View file

@ -318,9 +318,6 @@ pub unsafe extern "C" fn sp_brightness_grid_unsafe_data_ref(
assert_eq!(core::mem::size_of::<servicepoint::Brightness>(), 1);
let data = unsafe { (*brightness_grid).data_ref_mut() };
// this assumes more about the memory layout than rust guarantees. yikes!
let data: &mut [u8] = unsafe { transmute(data) };
SPByteSlice {
start: NonNull::new(data.as_mut_ptr_range().start).unwrap(),
length: data.len(),
}
unsafe { SPByteSlice::from_slice(transmute(data)) }
}

View file

@ -22,3 +22,22 @@ pub struct SPByteSlice {
/// The amount of memory in bytes
pub length: usize,
}
impl SPByteSlice {
pub(crate) unsafe fn as_slice(&self) -> &[u8] {
unsafe { std::slice::from_raw_parts(self.start.as_ptr(), self.length) }
}
pub(crate) unsafe fn as_slice_mut(&mut self) -> &mut [u8] {
unsafe {
std::slice::from_raw_parts_mut(self.start.as_ptr(), self.length)
}
}
pub(crate) unsafe fn from_slice(slice: &mut [u8]) -> Self {
Self {
start: NonNull::new(slice.as_mut_ptr()).unwrap(),
length: slice.len(),
}
}
}

View file

@ -280,9 +280,5 @@ pub unsafe extern "C" fn sp_cp437_grid_height(
pub unsafe extern "C" fn sp_cp437_grid_unsafe_data_ref(
cp437_grid: *mut SPCp437Grid,
) -> SPByteSlice {
let data = unsafe { (*cp437_grid).0.data_ref_mut() };
SPByteSlice {
start: NonNull::new(data.as_mut_ptr_range().start).unwrap(),
length: data.len(),
}
unsafe {SPByteSlice::from_slice((*cp437_grid).0.data_ref_mut()) }
}

View file

@ -5,8 +5,9 @@
//!
//! The raw packet
use std::ptr::NonNull;
use crate::SPByteSlice;
use servicepoint::{Header, Packet, TypedCommand};
use std::ptr::NonNull;
/// Turns a [SPCommand] into a [SPPacket].
/// The [SPCommand] gets consumed.
@ -107,19 +108,40 @@ pub unsafe extern "C" fn sp_packet_from_parts(
Vec::from(payload)
};
let packet = Box::new(Packet {
header,
payload,
});
let packet = Box::new(Packet { header, payload });
NonNull::from(Box::leak(packet))
}
#[no_mangle]
pub unsafe extern "C" fn sp_packet_get_header(
packet: *const Packet,
) -> Header {
pub unsafe extern "C" fn sp_packet_get_header(packet: *mut Packet) -> *mut Header {
assert!(!packet.is_null());
unsafe { (*packet).header }
&mut unsafe { (*packet).header }
}
#[no_mangle]
pub unsafe extern "C" fn sp_packet_get_payload(packet: *mut Packet) -> SPByteSlice {
assert!(!packet.is_null());
unsafe { SPByteSlice::from_slice(&mut *(*packet).payload) }
}
#[no_mangle]
pub unsafe extern "C" fn sp_packet_set_payload(packet: *mut Packet, data: SPByteSlice) {
assert!(!packet.is_null());
unsafe {
(*packet).payload = data.as_slice().to_vec()
}
}
#[no_mangle]
pub unsafe extern "C" fn sp_packet_write_to(
packet: *const Packet,
mut buffer: SPByteSlice,
) {
assert!(!packet.is_null());
unsafe {
(*packet).serialize_to(buffer.as_slice_mut());
}
}
/// Clones a [SPPacket].