From f7fddda8f1a3f974a03810467f0b47528ce34f9f Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sun, 13 Oct 2024 13:40:26 +0200 Subject: [PATCH 01/27] improve announce example --- crates/servicepoint/examples/announce.rs | 26 +++++++++++++++--------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/crates/servicepoint/examples/announce.rs b/crates/servicepoint/examples/announce.rs index ff95479..bb287b4 100644 --- a/crates/servicepoint/examples/announce.rs +++ b/crates/servicepoint/examples/announce.rs @@ -6,16 +6,26 @@ use servicepoint::{CharGrid, Command, Connection, Cp437Grid, Origin}; #[derive(Parser, Debug)] struct Cli { - #[arg(short, long, default_value = "localhost:2342")] + #[arg( + short, + long, + default_value = "localhost:2342", + help = "Address of the display" + )] destination: String, - #[arg(short, long, num_args = 1.., value_delimiter = '\n')] + #[arg(short, long, num_args = 1.., value_delimiter = '\n', + help = "Text to send - specify multiple times for multiple lines")] text: Vec, - #[arg(short, long, default_value_t = true)] + #[arg( + short, + long, + default_value_t = true, + help = "Clear screen before sending text" + )] clear: bool, } -/// example: `cargo run -- --text "Hallo, -/// CCCB"` +/// example: `cargo run -- --text "Hallo" --text "CCCB"` fn main() { let mut cli = Cli::parse(); if cli.text.is_empty() { @@ -31,11 +41,7 @@ fn main() { .expect("sending clear failed"); } - let text = cli.text.iter().fold(String::new(), move |str, line| { - let is_first = str.is_empty(); - str + if is_first { "" } else { "\n" } + line - }); - + let text = cli.text.join("\n"); let grid = CharGrid::from(&*text); let cp437_grid = Cp437Grid::from(&grid); From ce946c2fb8cd753ce8b33d2fd33a2d33102e2ebe Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sun, 13 Oct 2024 13:41:22 +0200 Subject: [PATCH 02/27] improve docs --- crates/servicepoint/src/command.rs | 11 +++-------- crates/servicepoint/src/cp437.rs | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/crates/servicepoint/src/command.rs b/crates/servicepoint/src/command.rs index abe983c..8422971 100644 --- a/crates/servicepoint/src/command.rs +++ b/crates/servicepoint/src/command.rs @@ -76,12 +76,7 @@ pub enum Command { /// Show text on the screen. /// - /// The text is sent in the form of a 2D grid of characters. - /// - ///
- /// The library does not currently convert between UTF-8 and CP-437. - /// Because Rust expects UTF-8 strings, it might be necessary to only send ASCII for now. - ///
+ /// The text is sent in the form of a 2D grid of [CP-437] encoded characters. /// /// # Examples /// @@ -100,6 +95,7 @@ pub enum Command { /// let grid = Cp437Grid::load_ascii("Hello\nWorld", 5, false).unwrap(); /// connection.send(Command::Cp437Data(Origin::new(2, 2), grid)).unwrap(); /// ``` + /// [CP-437]: https://en.wikipedia.org/wiki/Code_page_437 Cp437Data(Origin, Cp437Grid), /// Overwrites a rectangular region of pixels. @@ -217,9 +213,8 @@ pub enum Command { BitmapLegacy, } -#[derive(Debug)] /// Err values for [Command::try_from]. -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub enum TryFromPacketError { /// the contained command code does not correspond to a known command InvalidCommand(u16), diff --git a/crates/servicepoint/src/cp437.rs b/crates/servicepoint/src/cp437.rs index dc40627..d82d180 100644 --- a/crates/servicepoint/src/cp437.rs +++ b/crates/servicepoint/src/cp437.rs @@ -1,4 +1,7 @@ -use crate::cp437::Cp437LoadError::InvalidChar; +//! Conversion between UTF-8 and CP-437. +//! +//! Most of the functionality is only available with feature "cp437" enabled. + use crate::{Grid, PrimitiveGrid}; use std::collections::HashMap; @@ -10,9 +13,16 @@ pub type Cp437Grid = PrimitiveGrid; /// A grid containing UTF-8 characters. pub type CharGrid = PrimitiveGrid; +/// Errors that can occur when loading CP-437. #[derive(Debug)] pub enum Cp437LoadError { - InvalidChar { index: usize, char: char }, + /// Invalid character in input prevented loading + InvalidChar { + /// invalid character is at this position in input + index: usize, + /// the invalid character + char: char, + }, } impl Cp437Grid { From e1ca8022684238c0d67889d3eaf3076a16970299 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sun, 13 Oct 2024 13:42:20 +0200 Subject: [PATCH 03/27] CP437 conversion functions --- crates/servicepoint/src/cp437.rs | 77 ++++++++++++++++++++++++++------ crates/servicepoint/src/lib.rs | 2 +- 2 files changed, 65 insertions(+), 14 deletions(-) diff --git a/crates/servicepoint/src/cp437.rs b/crates/servicepoint/src/cp437.rs index d82d180..a2250b3 100644 --- a/crates/servicepoint/src/cp437.rs +++ b/crates/servicepoint/src/cp437.rs @@ -46,7 +46,7 @@ impl Cp437Grid { for (index, char) in value.chars().enumerate() { if !char.is_ascii() { - return Err(InvalidChar { index, char }); + return Err(Cp437LoadError::InvalidChar { index, char }); } let is_lf = char == '\n'; @@ -95,21 +95,15 @@ mod feature_cp437 { /// An array of 256 elements, mapping most of the CP437 values to UTF-8 characters /// - /// Mostly follows CP437, except for: - /// * 0x0A & 0x0D are kept for use as line endings. - /// * 0x1A is used for SAUCE. - /// * 0x1B is used for ANSI escape sequences. - /// - /// These exclusions should be fine since most programs can't even use them - /// without issues. And this makes rendering simpler too. + /// Mostly follows CP437, except 0x0A, which is kept for use as line ending. /// /// See /// - /// Copied from https://github.com/kip93/cp437-tools. License: GPL-3.0 + /// Mostly copied from https://github.com/kip93/cp437-tools. License: GPL-3.0 #[rustfmt::skip] - const CP437_TO_UTF8: [char; 256] = [ - /* 0X */ '\0', '☺', '☻', '♥', '♦', '♣', '♠', '•', '◘', '○', '\n', '♂', '♀', '\r', '♫', '☼', - /* 1X */ '►', '◄', '↕', '‼', '¶', '§', '▬', '↨', '↑', '↓', '', '', '∟', '↔', '▲', '▼', + pub const CP437_TO_UTF8: [char; 256] = [ + /* 0X */ '\0', '☺', '☻', '♥', '♦', '♣', '♠', '•', '◘', '○', '\n', '♂', '♀', '♪', '♫', '☼', + /* 1X */ '►', '◄', '↕', '‼', '¶', '§', '▬', '↨', '↑', '↓', '→', '←', '∟', '↔', '▲', '▼', /* 2X */ ' ', '!', '"', '#', '$', '%', '&', '\'','(', ')', '*', '+', ',', '-', '.', '/', /* 3X */ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', /* 4X */ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', @@ -187,6 +181,28 @@ mod feature_cp437 { grid } } + + /// Convert the provided bytes to UTF-8. + pub fn cp437_to_str(cp437: &[u8]) -> String { + cp437.iter().map(move |char| cp437_to_char(*char)).collect() + } + + /// Convert a single CP-437 character to UTF-8. + pub fn cp437_to_char(cp437: u8) -> char { + CP437_TO_UTF8[cp437 as usize] + } + + /// Convert the provided text to CP-437 bytes. + /// + /// Characters that are not available are mapped to '?'. + pub fn str_to_cp437(utf8: &str) -> Vec { + utf8.chars().map(char_to_cp437).collect() + } + + /// Convert a single UTF-8 character to CP-437. + pub fn char_to_cp437(utf8: char) -> u8 { + *UTF8_TO_CP437.get(&utf8).unwrap_or(&MISSING_CHAR_CP437) + } } #[cfg(test)] @@ -219,7 +235,7 @@ mod tests { #[cfg(test)] #[cfg(feature = "cp437")] mod tests_feature_cp437 { - use crate::{CharGrid, Cp437Grid}; + use super::*; #[test] fn round_trip_cp437() { @@ -228,4 +244,39 @@ mod tests_feature_cp437 { let actual = CharGrid::from(&cp437); assert_eq!(actual, utf8); } + + #[test] + fn convert_str() { + // test text from https://int10h.org/oldschool-pc-fonts/fontlist/font?ibm_bios + let utf8 = r#"A quick brown fox jumps over the lazy dog. + 0123456789 ¿?¡!`'"., <>()[]{} &@%*^#$\/ + + * Wieniläinen sioux'ta puhuva ökyzombie diggaa Åsan roquefort-tacoja. + * Ça me fait peur de fêter noël là, sur cette île bizarroïde où une mère et sa môme essaient de me tuer avec un gâteau à la cigüe brûlé. + * Zwölf Boxkämpfer jagten Eva quer über den Sylter Deich. + * El pingüino Wenceslao hizo kilómetros bajo exhaustiva lluvia y frío, añoraba a su querido cachorro. + + ┌─┬─┐ ╔═╦═╗ ╒═╤═╕ ╓─╥─╖ + │ │ │ ║ ║ ║ │ │ │ ║ ║ ║ + ├─┼─┤ ╠═╬═╣ ╞═╪═╡ ╟─╫─╢ + └─┴─┘ ╚═╩═╝ ╘═╧═╛ ╙─╨─╜ + + ░░░░░ ▐▀█▀▌ .·∙•○°○•∙·. + ▒▒▒▒▒ ▐ █ ▌ ☺☻ ♥♦♣♠ ♪♫☼ + ▓▓▓▓▓ ▐▀█▀▌ $ ¢ £ ¥ ₧ + █████ ▐▄█▄▌ ◄►▲▼ ←→↑↓↕↨ + + ⌠ + │dx ≡ Σ √x²ⁿ·δx + ⌡"#; + + let cp437 = str_to_cp437(utf8); + let actual = cp437_to_str(&*cp437); + assert_eq!(utf8, actual) + } + + #[test] + fn convert_invalid() { + assert_eq!(cp437_to_char(char_to_cp437('😜')), '?'); + } } diff --git a/crates/servicepoint/src/lib.rs b/crates/servicepoint/src/lib.rs index fa5564e..d644bba 100644 --- a/crates/servicepoint/src/lib.rs +++ b/crates/servicepoint/src/lib.rs @@ -59,7 +59,7 @@ mod command_code; mod compression; mod compression_code; mod connection; -mod cp437; +pub mod cp437; mod data_ref; mod grid; mod origin; From 526f6264bff69ed32fffc7b22df3a08363a0116c Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sun, 13 Oct 2024 16:13:12 +0200 Subject: [PATCH 04/27] easier conversion of PrimitiveGrids --- crates/servicepoint/src/cp437.rs | 25 ++--------------------- crates/servicepoint/src/primitive_grid.rs | 10 +++++++++ 2 files changed, 12 insertions(+), 23 deletions(-) diff --git a/crates/servicepoint/src/cp437.rs b/crates/servicepoint/src/cp437.rs index a2250b3..5909296 100644 --- a/crates/servicepoint/src/cp437.rs +++ b/crates/servicepoint/src/cp437.rs @@ -133,34 +133,13 @@ mod feature_cp437 { impl From<&Cp437Grid> for CharGrid { fn from(value: &Cp437Grid) -> Self { - let mut grid = Self::new(value.width(), value.height()); - - for y in 0..grid.height() { - for x in 0..grid.width() { - let converted = CP437_TO_UTF8[value.get(x, y) as usize]; - grid.set(x, y, converted); - } - } - - grid + value.convert(move |cp437| cp437_to_char(*cp437)) } } impl From<&CharGrid> for Cp437Grid { fn from(value: &CharGrid) -> Self { - let mut grid = Self::new(value.width(), value.height()); - - for y in 0..grid.height() { - for x in 0..grid.width() { - let char = value.get(x, y); - let converted = *UTF8_TO_CP437 - .get(&char) - .unwrap_or(&MISSING_CHAR_CP437); - grid.set(x, y, converted); - } - } - - grid + value.convert(move |char| char_to_cp437(*char)) } } diff --git a/crates/servicepoint/src/primitive_grid.rs b/crates/servicepoint/src/primitive_grid.rs index 2b02ca3..0b947b6 100644 --- a/crates/servicepoint/src/primitive_grid.rs +++ b/crates/servicepoint/src/primitive_grid.rs @@ -110,6 +110,16 @@ impl PrimitiveGrid { None } } + + /// Convert between PrimitiveGrid types + pub fn convert(&self, f: F) -> PrimitiveGrid + where + TConverted: PrimitiveGridType, + F: FnMut(&T) -> TConverted, + { + let data = self.data_ref().iter().map(f).collect::>(); + PrimitiveGrid::load(self.width(), self.height(), &*data) + } } impl Grid for PrimitiveGrid { From ab82900414e4066a7263e7e051a49a24bf47a4cc Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sun, 13 Oct 2024 16:31:03 +0200 Subject: [PATCH 05/27] improve whitespace handling when converting between string and grid --- crates/servicepoint/src/cp437.rs | 34 +++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/crates/servicepoint/src/cp437.rs b/crates/servicepoint/src/cp437.rs index 5909296..f779025 100644 --- a/crates/servicepoint/src/cp437.rs +++ b/crates/servicepoint/src/cp437.rs @@ -146,10 +146,17 @@ mod feature_cp437 { impl From<&str> for CharGrid { fn from(value: &str) -> Self { let value = value.replace("\r\n", "\n"); - let lines = value.split('\n').collect::>(); + let mut lines = value + .split('\n') + .map(move |line| line.trim_end()) + .collect::>(); let width = lines.iter().fold(0, move |a, x| std::cmp::max(a, x.len())); + while lines.last().is_some_and(move |line| line.is_empty()) { + _ = lines.pop(); + } + let mut grid = Self::new(width, lines.len()); for (y, line) in lines.iter().enumerate() { for (x, char) in line.chars().enumerate() { @@ -161,6 +168,22 @@ mod feature_cp437 { } } + impl From<&CharGrid> for String { + fn from(value: &CharGrid) -> Self { + value + .iter_rows() + .map(move |chars| { + chars + .collect::() + .replace('\0', " ") + .trim_end() + .to_string() + }) + .collect::>() + .join("\n") + } + } + /// Convert the provided bytes to UTF-8. pub fn cp437_to_str(cp437: &[u8]) -> String { cp437.iter().map(move |char| cp437_to_char(*char)).collect() @@ -258,4 +281,13 @@ mod tests_feature_cp437 { fn convert_invalid() { assert_eq!(cp437_to_char(char_to_cp437('😜')), '?'); } + + #[test] + fn str_to_char_grid() { + let original = "Hello\r\nWorld!\n...\n"; + let grid = CharGrid::from(original); + assert_eq!(3, grid.height()); + let actual = String::from(&grid); + assert_eq!("Hello\nWorld!\n...", actual); + } } From be17319993bdc4e5db754c51dd3a2830d64be17c Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sun, 13 Oct 2024 16:51:32 +0200 Subject: [PATCH 06/27] add unit tests --- crates/servicepoint/src/command.rs | 26 +++++++++++++++++++++++++- crates/servicepoint/src/cp437.rs | 13 ++++++++++++- crates/servicepoint/src/grid.rs | 14 ++++---------- 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/crates/servicepoint/src/command.rs b/crates/servicepoint/src/command.rs index 8422971..210ab01 100644 --- a/crates/servicepoint/src/command.rs +++ b/crates/servicepoint/src/command.rs @@ -495,7 +495,8 @@ mod tests { command_code::CommandCode, origin::Pixels, packet::{Header, Packet}, - Brightness, Command, CompressionCode, Origin, PixelGrid, PrimitiveGrid, + Brightness, BrightnessGrid, Command, CompressionCode, Origin, + PixelGrid, PrimitiveGrid, }; fn round_trip(original: Command) { @@ -902,4 +903,27 @@ mod tests { Origin::new(1, 0) + Origin::new(3, 2) ); } + #[test] + fn packet_into_char_brightness_invalid() { + let grid = BrightnessGrid::new(2, 2); + let command = Command::CharBrightness(Origin::ZERO, grid); + let mut packet: Packet = command.into(); + let slot = packet.payload.get_mut(1).unwrap(); + *slot = 23; + assert_eq!( + Command::try_from(packet), + Err(TryFromPacketError::InvalidBrightness(23)) + ); + } + + #[test] + fn packet_into_brightness_invalid() { + let mut packet: Packet = Command::Brightness(Brightness::MAX).into(); + let slot = packet.payload.get_mut(0).unwrap(); + *slot = 42; + assert_eq!( + Command::try_from(packet), + Err(TryFromPacketError::InvalidBrightness(42)) + ); + } } diff --git a/crates/servicepoint/src/cp437.rs b/crates/servicepoint/src/cp437.rs index f779025..1a4b25d 100644 --- a/crates/servicepoint/src/cp437.rs +++ b/crates/servicepoint/src/cp437.rs @@ -14,7 +14,7 @@ pub type Cp437Grid = PrimitiveGrid; pub type CharGrid = PrimitiveGrid; /// Errors that can occur when loading CP-437. -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum Cp437LoadError { /// Invalid character in input prevented loading InvalidChar { @@ -232,6 +232,17 @@ mod tests { // line break will be added assert_eq!(actual, expected); } + + #[test] + fn load_ascii_invalid() { + assert_eq!( + Err(Cp437LoadError::InvalidChar { + char: '🥶', + index: 2 + }), + Cp437Grid::load_ascii("?#🥶42", 3, false) + ); + } } #[cfg(test)] diff --git a/crates/servicepoint/src/grid.rs b/crates/servicepoint/src/grid.rs index d367d98..68fe102 100644 --- a/crates/servicepoint/src/grid.rs +++ b/crates/servicepoint/src/grid.rs @@ -76,15 +76,9 @@ pub trait Grid { /// /// When the specified position is out of bounds for this grid. fn assert_in_bounds(&self, x: usize, y: usize) { - assert!( - x < self.width(), - "cannot access index [{x}, {y}] because x is outside of bounds 0..{}", - self.width() - 1 - ); - assert!( - y < self.height(), - "cannot access index [{x}, {y}] because y is outside of bounds 0..{}", - self.height() - 1 - ); + let width = self.width(); + assert!(x < width, "cannot access index [{x}, {y}] because x is outside of bounds [0..{width})"); + let height = self.height(); + assert!(y < height, "cannot access index [{x}, {y}] because x is outside of bounds [0..{height})"); } } From 68d809c71488e059e777809d3b12e821c796b769 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sun, 13 Oct 2024 17:36:32 +0200 Subject: [PATCH 07/27] prefix enum names for better C consumption --- crates/servicepoint_binding_c/cbindgen.toml | 3 +++ .../examples/lang_c/include/servicepoint.h | 10 +++++----- .../servicepoint_binding_c/examples/lang_c/src/main.c | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/crates/servicepoint_binding_c/cbindgen.toml b/crates/servicepoint_binding_c/cbindgen.toml index 1114264..cbf9e14 100644 --- a/crates/servicepoint_binding_c/cbindgen.toml +++ b/crates/servicepoint_binding_c/cbindgen.toml @@ -31,3 +31,6 @@ all_features = true [export] include = [] exclude = [] + +[enum] +rename_variants = "QualifiedScreamingSnakeCase" diff --git a/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h b/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h index f431793..453c6b1 100644 --- a/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h +++ b/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h @@ -49,23 +49,23 @@ enum SPCompressionCode /** * no compression */ - Uncompressed = 0, + SP_COMPRESSION_CODE_UNCOMPRESSED = 0, /** * compress using flate2 with zlib header */ - Zlib = 26490, + SP_COMPRESSION_CODE_ZLIB = 26490, /** * compress using bzip2 */ - Bzip2 = 25210, + SP_COMPRESSION_CODE_BZIP2 = 25210, /** * compress using lzma */ - Lzma = 27770, + SP_COMPRESSION_CODE_LZMA = 27770, /** * compress using Zstandard */ - Zstd = 31347, + SP_COMPRESSION_CODE_ZSTD = 31347, }; #ifndef __cplusplus typedef uint16_t SPCompressionCode; diff --git a/crates/servicepoint_binding_c/examples/lang_c/src/main.c b/crates/servicepoint_binding_c/examples/lang_c/src/main.c index 5054286..6c23ab0 100644 --- a/crates/servicepoint_binding_c/examples/lang_c/src/main.c +++ b/crates/servicepoint_binding_c/examples/lang_c/src/main.c @@ -9,7 +9,7 @@ int main(void) { SPPixelGrid *pixels = sp_pixel_grid_new(SP_PIXEL_WIDTH, SP_PIXEL_HEIGHT); sp_pixel_grid_fill(pixels, true); - SPCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, Uncompressed); + SPCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, SP_COMPRESSION_CODE_UNCOMPRESSED); while (sp_connection_send_command(connection, sp_command_clone(command))); sp_command_free(command); From 03becf19b50e22a6959eea6984d298f22dc65dc6 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sun, 13 Oct 2024 18:12:55 +0200 Subject: [PATCH 08/27] add NULL checks - bit_vec --- crates/servicepoint_binding_c/src/bit_vec.rs | 107 +++++++++++++----- .../src/brightness_grid.rs | 4 +- crates/servicepoint_binding_c/src/command.rs | 66 +++++------ .../servicepoint_binding_c/src/connection.rs | 2 +- .../servicepoint_binding_c/src/cp437_grid.rs | 4 +- crates/servicepoint_binding_c/src/packet.rs | 8 +- .../servicepoint_binding_c/src/pixel_grid.rs | 2 +- 7 files changed, 120 insertions(+), 73 deletions(-) diff --git a/crates/servicepoint_binding_c/src/bit_vec.rs b/crates/servicepoint_binding_c/src/bit_vec.rs index d1b353c..8b9e94f 100644 --- a/crates/servicepoint_binding_c/src/bit_vec.rs +++ b/crates/servicepoint_binding_c/src/bit_vec.rs @@ -1,4 +1,4 @@ -//! C functions for interacting with `SPBitVec`s +//! C functions for interacting with [SPBitVec]s //! //! prefix `sp_bit_vec_` @@ -33,17 +33,17 @@ impl Clone for SPBitVec { } } -/// Creates a new `SPBitVec` instance. +/// Creates a new [SPBitVec] instance. /// /// # Arguments /// /// - `size`: size in bits. /// -/// returns: `SPBitVec` with all bits set to false. Will never return NULL. +/// returns: [SPBitVec] with all bits set to false. Will never return NULL. /// /// # Panics /// -/// When `size` is not divisible by 8. +/// - when `size` is not divisible by 8. /// /// # Safety /// @@ -53,10 +53,18 @@ impl Clone for SPBitVec { /// by explicitly calling `sp_bit_vec_free`. #[no_mangle] pub unsafe extern "C" fn sp_bit_vec_new(size: usize) -> *mut SPBitVec { - Box::into_raw(Box::new(SPBitVec(BitVec::repeat(false, size)))) + let result = Box::into_raw(Box::new(SPBitVec(BitVec::repeat(false, size)))); + assert!(!result.is_null()); + 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. +/// +/// returns: [SPBitVec] instance containing data. Will never return NULL. +/// +/// # Panics +/// +/// - when `data` is NULL /// /// # Safety /// @@ -71,17 +79,26 @@ pub unsafe extern "C" fn sp_bit_vec_load( data: *const u8, data_length: usize, ) -> *mut SPBitVec { + assert!(!data.is_null()); let data = std::slice::from_raw_parts(data, data_length); - Box::into_raw(Box::new(SPBitVec(BitVec::from_slice(data)))) + let result = Box::into_raw(Box::new(SPBitVec(BitVec::from_slice(data)))); + assert!(!result.is_null()); + result } -/// Clones a `SPBitVec`. +/// Clones a [SPBitVec]. +/// +/// returns: new [SPBitVec] instance. Will never return NULL. +/// +/// # Panics +/// +/// - when `bit_vec` is NULL /// /// # Safety /// /// The caller has to make sure that: /// -/// - `bit_vec` points to a valid `SPBitVec` +/// - `bit_vec` points to a valid [SPBitVec] /// - `bit_vec` is not written to concurrently /// - the returned instance is freed in some way, either by using a consuming function or /// by explicitly calling `sp_bit_vec_free`. @@ -89,24 +106,32 @@ pub unsafe extern "C" fn sp_bit_vec_load( pub unsafe extern "C" fn sp_bit_vec_clone( bit_vec: *const SPBitVec, ) -> *mut SPBitVec { - Box::into_raw(Box::new((*bit_vec).clone())) + assert!(!bit_vec.is_null()); + let result = Box::into_raw(Box::new((*bit_vec).clone())); + assert!(!result.is_null()); + result } -/// Deallocates a `SPBitVec`. +/// Deallocates a [SPBitVec]. +/// +/// # Panics +/// +/// - when `but_vec` is NULL /// /// # Safety /// /// The caller has to make sure that: /// -/// - `bit_vec` points to a valid `SPBitVec` +/// - `bit_vec` points to a valid [SPBitVec] /// - `bit_vec` is not used concurrently or after this call -/// - `bit_vec` was not passed to another consuming function, e.g. to create a `SPCommand` +/// - `bit_vec` was not passed to another consuming function, e.g. to create a [SPCommand] #[no_mangle] pub unsafe extern "C" fn sp_bit_vec_free(bit_vec: *mut SPBitVec) { + assert!(!bit_vec.is_null()); _ = Box::from_raw(bit_vec); } -/// Gets the value of a bit from the `SPBitVec`. +/// Gets the value of a bit from the [SPBitVec]. /// /// # Arguments /// @@ -117,23 +142,25 @@ pub unsafe extern "C" fn sp_bit_vec_free(bit_vec: *mut SPBitVec) { /// /// # Panics /// -/// When accessing `index` out of bounds. +/// - when `bit_vec` is NULL +/// - when accessing `index` out of bounds /// /// # Safety /// /// The caller has to make sure that: /// -/// - `bit_vec` points to a valid `SPBitVec` +/// - `bit_vec` points to a valid [SPBitVec] /// - `bit_vec` is not written to concurrently #[no_mangle] pub unsafe extern "C" fn sp_bit_vec_get( bit_vec: *const SPBitVec, index: usize, ) -> bool { + assert!(!bit_vec.is_null()); *(*bit_vec).0.get(index).unwrap() } -/// Sets the value of a bit in the `SPBitVec`. +/// Sets the value of a bit in the [SPBitVec]. /// /// # Arguments /// @@ -141,17 +168,16 @@ pub unsafe extern "C" fn sp_bit_vec_get( /// - `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. +/// - when `bit_vec` is NULL +/// - when accessing `index` out of bounds /// /// # Safety /// /// The caller has to make sure that: /// -/// - `bit_vec` points to a valid `SPBitVec` +/// - `bit_vec` points to a valid [SPBitVec] /// - `bit_vec` is not written to or read from concurrently #[no_mangle] pub unsafe extern "C" fn sp_bit_vec_set( @@ -159,40 +185,51 @@ pub unsafe extern "C" fn sp_bit_vec_set( index: usize, value: bool, ) { + assert!(!bit_vec.is_null()); (*bit_vec).0.set(index, value) } -/// Sets the value of all bits in the `SPBitVec`. +/// Sets the value of all bits in the [SPBitVec]. /// /// # Arguments /// /// - `bit_vec`: instance to write to /// - `value`: the value to set all bits to /// +/// # Panics +/// +/// - when `bit_vec` is NULL +/// /// # Safety /// /// The caller has to make sure that: /// -/// - `bit_vec` points to a valid `SPBitVec` +/// - `bit_vec` points to a valid [SPBitVec] /// - `bit_vec` is not written to or read from concurrently #[no_mangle] pub unsafe extern "C" fn sp_bit_vec_fill(bit_vec: *mut SPBitVec, value: bool) { + assert!(!bit_vec.is_null()); (*bit_vec).0.fill(value) } -/// Gets the length of the `SPBitVec` in bits. +/// Gets the length of the [SPBitVec] in bits. /// /// # Arguments /// /// - `bit_vec`: instance to write to /// +/// # Panics +/// +/// - when `bit_vec` is NULL +/// /// # Safety /// /// The caller has to make sure that: /// -/// - `bit_vec` points to a valid `SPBitVec` +/// - `bit_vec` points to a valid [SPBitVec] #[no_mangle] pub unsafe extern "C" fn sp_bit_vec_len(bit_vec: *const SPBitVec) -> usize { + assert!(!bit_vec.is_null()); (*bit_vec).0.len() } @@ -202,33 +239,43 @@ pub unsafe extern "C" fn sp_bit_vec_len(bit_vec: *const SPBitVec) -> usize { /// /// - `bit_vec`: instance to write to /// +/// # Panics +/// +/// - when `bit_vec` is NULL +/// /// # Safety /// /// The caller has to make sure that: /// -/// - `bit_vec` points to a valid `SPBitVec` +/// - `bit_vec` points to a valid [SPBitVec] #[no_mangle] pub unsafe extern "C" fn sp_bit_vec_is_empty(bit_vec: *const SPBitVec) -> bool { + assert!(!bit_vec.is_null()); (*bit_vec).0.is_empty() } -/// Gets an unsafe reference to the data of the `SPBitVec` instance. +/// Gets an unsafe reference to the data of the [SPBitVec] instance. /// /// # Arguments /// /// - `bit_vec`: instance to write to /// +/// # Panics +/// +/// - when `bit_vec` is NULL +/// /// ## Safety /// /// The caller has to make sure that: /// -/// - `bit_vec` points to a valid `SPBitVec` -/// - the returned memory range is never accessed after the passed `SPBitVec` has been freed -/// - the returned memory range is never accessed concurrently, either via the `SPBitVec` or directly +/// - `bit_vec` points to a valid [SPBitVec] +/// - the returned memory range is never accessed after the passed [SPBitVec] has been freed +/// - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly #[no_mangle] pub unsafe extern "C" fn sp_bit_vec_unsafe_data_ref( bit_vec: *mut SPBitVec, ) -> SPByteSlice { + assert!(!bit_vec.is_null()); let data = (*bit_vec).0.as_raw_mut_slice(); SPByteSlice { start: data.as_mut_ptr_range().start, diff --git a/crates/servicepoint_binding_c/src/brightness_grid.rs b/crates/servicepoint_binding_c/src/brightness_grid.rs index a34ecf2..33662ff 100644 --- a/crates/servicepoint_binding_c/src/brightness_grid.rs +++ b/crates/servicepoint_binding_c/src/brightness_grid.rs @@ -110,7 +110,7 @@ pub unsafe extern "C" fn sp_brightness_grid_clone( /// /// - `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` +/// - `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, @@ -163,7 +163,7 @@ pub unsafe extern "C" fn sp_brightness_grid_get( /// /// The caller has to make sure that: /// -/// - `brightness_grid` points to a valid `SPBitVec` +/// - `brightness_grid` points to a valid [SPBitVec] /// - `brightness_grid` is not written to or read from concurrently #[no_mangle] pub unsafe extern "C" fn sp_brightness_grid_set( diff --git a/crates/servicepoint_binding_c/src/command.rs b/crates/servicepoint_binding_c/src/command.rs index d98b99f..7bc956a 100644 --- a/crates/servicepoint_binding_c/src/command.rs +++ b/crates/servicepoint_binding_c/src/command.rs @@ -1,4 +1,4 @@ -//! C functions for interacting with `SPCommand`s +//! C functions for interacting with [SPCommand]s //! //! prefix `sp_command_` @@ -15,7 +15,7 @@ use crate::{ /// /// This struct and associated functions implement the UDP protocol for the display. /// -/// To send a `SPCommand`, use a `SPConnection`. +/// To send a [SPCommand], use a `SPConnection`. /// /// # Examples /// @@ -31,11 +31,11 @@ impl Clone for SPCommand { } } -/// Tries to turn a `SPPacket` into a `SPCommand`. +/// Tries to turn a `SPPacket` into a [SPCommand]. /// /// The packet is deallocated in the process. /// -/// Returns: pointer to new `SPCommand` instance or NULL +/// Returns: pointer to new [SPCommand] instance or NULL /// /// # Safety /// @@ -44,7 +44,7 @@ impl Clone for SPCommand { /// - `SPPacket` points to a valid instance of `SPPacket` /// - `SPPacket` is not used concurrently or after this call /// - the result is checked for NULL -/// - 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`. #[no_mangle] pub unsafe extern "C" fn sp_command_try_from_packet( @@ -57,15 +57,15 @@ pub unsafe extern "C" fn sp_command_try_from_packet( } } -/// Clones a `SPCommand` instance. +/// Clones a [SPCommand] instance. /// /// # Safety /// /// The caller has to make sure that: /// -/// - `command` points to a valid instance of `SPCommand` +/// - `command` points to a valid instance of [SPCommand] /// - `command` is not written to concurrently -/// - 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`. #[no_mangle] pub unsafe extern "C" fn sp_command_clone( @@ -90,7 +90,7 @@ pub unsafe extern "C" fn sp_command_clone( /// /// The caller has to make sure that: /// -/// - 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`. #[no_mangle] pub unsafe extern "C" fn sp_command_clear() -> *mut SPCommand { @@ -107,7 +107,7 @@ pub unsafe extern "C" fn sp_command_clear() -> *mut SPCommand { /// /// The caller has to make sure that: /// -/// - 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`. #[no_mangle] pub unsafe extern "C" fn sp_command_hard_reset() -> *mut SPCommand { @@ -122,7 +122,7 @@ pub unsafe extern "C" fn sp_command_hard_reset() -> *mut SPCommand { /// /// The caller has to make sure that: /// -/// - 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`. #[no_mangle] pub unsafe extern "C" fn sp_command_fade_out() -> *mut SPCommand { @@ -141,7 +141,7 @@ pub unsafe extern "C" fn sp_command_fade_out() -> *mut SPCommand { /// /// The caller has to make sure that: /// -/// - 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`. #[no_mangle] pub unsafe extern "C" fn sp_command_brightness( @@ -166,7 +166,7 @@ pub unsafe extern "C" fn sp_command_brightness( /// /// - `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 +/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or /// by explicitly calling `sp_command_free`. #[no_mangle] pub unsafe extern "C" fn sp_command_char_brightness( @@ -186,9 +186,9 @@ pub unsafe extern "C" fn sp_command_char_brightness( /// The screen will continuously overwrite more pixel data without regarding the offset, meaning /// once the starting row is full, overwriting will continue on column 0. /// -/// The contained `SPBitVec` is always uncompressed. +/// The contained [SPBitVec] is always uncompressed. /// -/// The passed `SPBitVec` gets consumed. +/// The passed [SPBitVec] gets consumed. /// /// Returns: a new `Command::BitmapLinear` instance. Will never return NULL. /// @@ -196,10 +196,10 @@ pub unsafe extern "C" fn sp_command_char_brightness( /// /// The caller has to make sure that: /// -/// - `bit_vec` points to a valid instance of `SPBitVec` +/// - `bit_vec` points to a valid instance of [SPBitVec] /// - `bit_vec` is not used concurrently or after this call /// - `compression` matches one of the allowed enum values -/// - 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`. #[no_mangle] pub unsafe extern "C" fn sp_command_bitmap_linear( @@ -220,9 +220,9 @@ pub unsafe extern "C" fn sp_command_bitmap_linear( /// The screen will continuously overwrite more pixel data without regarding the offset, meaning /// once the starting row is full, overwriting will continue on column 0. /// -/// The contained `SPBitVec` is always uncompressed. +/// The contained [SPBitVec] is always uncompressed. /// -/// The passed `SPBitVec` gets consumed. +/// The passed [SPBitVec] gets consumed. /// /// Returns: a new `Command::BitmapLinearAnd` instance. Will never return NULL. /// @@ -230,10 +230,10 @@ pub unsafe extern "C" fn sp_command_bitmap_linear( /// /// The caller has to make sure that: /// -/// - `bit_vec` points to a valid instance of `SPBitVec` +/// - `bit_vec` points to a valid instance of [SPBitVec] /// - `bit_vec` is not used concurrently or after this call /// - `compression` matches one of the allowed enum values -/// - 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`. #[no_mangle] pub unsafe extern "C" fn sp_command_bitmap_linear_and( @@ -254,9 +254,9 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_and( /// The screen will continuously overwrite more pixel data without regarding the offset, meaning /// once the starting row is full, overwriting will continue on column 0. /// -/// The contained `SPBitVec` is always uncompressed. +/// The contained [SPBitVec] is always uncompressed. /// -/// The passed `SPBitVec` gets consumed. +/// The passed [SPBitVec] gets consumed. /// /// Returns: a new `Command::BitmapLinearOr` instance. Will never return NULL. /// @@ -264,10 +264,10 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_and( /// /// The caller has to make sure that: /// -/// - `bit_vec` points to a valid instance of `SPBitVec` +/// - `bit_vec` points to a valid instance of [SPBitVec] /// - `bit_vec` is not used concurrently or after this call /// - `compression` matches one of the allowed enum values -/// - 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`. #[no_mangle] pub unsafe extern "C" fn sp_command_bitmap_linear_or( @@ -288,9 +288,9 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_or( /// The screen will continuously overwrite more pixel data without regarding the offset, meaning /// once the starting row is full, overwriting will continue on column 0. /// -/// The contained `SPBitVec` is always uncompressed. +/// The contained [SPBitVec] is always uncompressed. /// -/// The passed `SPBitVec` gets consumed. +/// The passed [SPBitVec] gets consumed. /// /// Returns: a new `Command::BitmapLinearXor` instance. Will never return NULL. /// @@ -298,10 +298,10 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_or( /// /// The caller has to make sure that: /// -/// - `bit_vec` points to a valid instance of `SPBitVec` +/// - `bit_vec` points to a valid instance of [SPBitVec] /// - `bit_vec` is not used concurrently or after this call /// - `compression` matches one of the allowed enum values -/// - 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`. #[no_mangle] pub unsafe extern "C" fn sp_command_bitmap_linear_xor( @@ -334,7 +334,7 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_xor( /// /// - `grid` points to a valid instance of `SPCp437Grid` /// - `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`. #[no_mangle] pub unsafe extern "C" fn sp_command_cp437_data( @@ -362,7 +362,7 @@ pub unsafe extern "C" fn sp_command_cp437_data( /// - `pixel_grid` points to a valid instance of `SPPixelGrid` /// - `pixel_grid` is not used concurrently or after this call /// - `compression` matches one of the allowed enum values -/// - 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`. #[no_mangle] pub unsafe extern "C" fn sp_command_bitmap_linear_win( @@ -381,7 +381,7 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_win( )))) } -/// Deallocates a `SPCommand`. +/// Deallocates a [SPCommand]. /// /// # Examples /// @@ -394,7 +394,7 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_win( /// /// The caller has to make sure that: /// -/// - `command` points to a valid `SPCommand` +/// - `command` points to a valid [SPCommand] /// - `command` is not used concurrently or after this call /// - `command` was not passed to another consuming function, e.g. to create a `SPPacket` #[no_mangle] diff --git a/crates/servicepoint_binding_c/src/connection.rs b/crates/servicepoint_binding_c/src/connection.rs index 846b607..ee630a9 100644 --- a/crates/servicepoint_binding_c/src/connection.rs +++ b/crates/servicepoint_binding_c/src/connection.rs @@ -67,7 +67,7 @@ pub unsafe extern "C" fn sp_connection_send_packet( (*connection).0.send((*packet).0).is_ok() } -/// Sends a `SPCommand` to the display using the `SPConnection`. +/// Sends a [SPCommand] to the display using the `SPConnection`. /// /// The passed `command` gets consumed. /// diff --git a/crates/servicepoint_binding_c/src/cp437_grid.rs b/crates/servicepoint_binding_c/src/cp437_grid.rs index 781c345..38d4af0 100644 --- a/crates/servicepoint_binding_c/src/cp437_grid.rs +++ b/crates/servicepoint_binding_c/src/cp437_grid.rs @@ -101,7 +101,7 @@ pub unsafe extern "C" fn sp_cp437_grid_clone( /// /// - `cp437_grid` points to a valid `SPCp437Grid` /// - `cp437_grid` is not used concurrently or after cp437_grid call -/// - `cp437_grid` was not passed to another consuming function, e.g. to create a `SPCommand` +/// - `cp437_grid` was not passed to another consuming function, e.g. to create a [SPCommand] #[no_mangle] pub unsafe extern "C" fn sp_cp437_grid_free(cp437_grid: *mut SPCp437Grid) { _ = Box::from_raw(cp437_grid); @@ -151,7 +151,7 @@ pub unsafe extern "C" fn sp_cp437_grid_get( /// /// The caller has to make sure that: /// -/// - `cp437_grid` points to a valid `SPBitVec` +/// - `cp437_grid` points to a valid [SPBitVec] /// - `cp437_grid` is not written to or read from concurrently #[no_mangle] pub unsafe extern "C" fn sp_cp437_grid_set( diff --git a/crates/servicepoint_binding_c/src/packet.rs b/crates/servicepoint_binding_c/src/packet.rs index 5dc5820..d8a0302 100644 --- a/crates/servicepoint_binding_c/src/packet.rs +++ b/crates/servicepoint_binding_c/src/packet.rs @@ -9,8 +9,8 @@ use crate::SPCommand; /// The raw packet pub struct SPPacket(pub(crate) servicepoint::packet::Packet); -/// Turns a `SPCommand` into a `SPPacket`. -/// The `SPCommand` gets consumed. +/// Turns a [SPCommand] into a `SPPacket`. +/// The [SPCommand] gets consumed. /// /// Will never return NULL. /// @@ -18,8 +18,8 @@ pub struct SPPacket(pub(crate) servicepoint::packet::Packet); /// /// The caller has to make sure that: /// -/// - `SPCommand` points to a valid instance of `SPCommand` -/// - `SPCommand` is not used concurrently or after this call +/// - [SPCommand] points to a valid instance of [SPCommand] +/// - [SPCommand] is not used concurrently or after this call /// - the returned `SPPacket` instance is freed in some way, either by using a consuming function or /// by explicitly calling `sp_packet_free`. #[no_mangle] diff --git a/crates/servicepoint_binding_c/src/pixel_grid.rs b/crates/servicepoint_binding_c/src/pixel_grid.rs index 780c305..e032d50 100644 --- a/crates/servicepoint_binding_c/src/pixel_grid.rs +++ b/crates/servicepoint_binding_c/src/pixel_grid.rs @@ -108,7 +108,7 @@ pub unsafe extern "C" fn sp_pixel_grid_clone( /// /// - `pixel_grid` points to a valid `SPPixelGrid` /// - `pixel_grid` is not used concurrently or after pixel_grid call -/// - `pixel_grid` was not passed to another consuming function, e.g. to create a `SPCommand` +/// - `pixel_grid` was not passed to another consuming function, e.g. to create a [SPCommand] #[no_mangle] pub unsafe extern "C" fn sp_pixel_grid_free(pixel_grid: *mut SPPixelGrid) { _ = Box::from_raw(pixel_grid); From bcb73999da7fc3da4b609789f1fe13c41f8efc33 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sun, 13 Oct 2024 18:22:26 +0200 Subject: [PATCH 09/27] add NULL checks - brightness_grid --- .../src/brightness_grid.rs | 106 +++++++++++++----- crates/servicepoint_binding_c/src/command.rs | 4 +- 2 files changed, 80 insertions(+), 30 deletions(-) diff --git a/crates/servicepoint_binding_c/src/brightness_grid.rs b/crates/servicepoint_binding_c/src/brightness_grid.rs index 33662ff..db44687 100644 --- a/crates/servicepoint_binding_c/src/brightness_grid.rs +++ b/crates/servicepoint_binding_c/src/brightness_grid.rs @@ -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::(), 1); - let data = (*brightness_grid).0.data_ref_mut(); let data: &mut [u8] = transmute(data); SPByteSlice { diff --git a/crates/servicepoint_binding_c/src/command.rs b/crates/servicepoint_binding_c/src/command.rs index 7bc956a..4e5b45b 100644 --- a/crates/servicepoint_binding_c/src/command.rs +++ b/crates/servicepoint_binding_c/src/command.rs @@ -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`. From 2e1cb6f6816e848fe1fff2ecb3a399462cc2ea6d Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sun, 13 Oct 2024 18:56:29 +0200 Subject: [PATCH 10/27] add NULL checks - command --- crates/servicepoint_binding_c/src/command.rs | 165 +++++++++++++----- .../servicepoint_binding_c/src/connection.rs | 22 ++- .../servicepoint_binding_c/src/cp437_grid.rs | 40 ++--- crates/servicepoint_binding_c/src/packet.rs | 18 +- .../servicepoint_binding_c/src/pixel_grid.rs | 46 ++--- 5 files changed, 186 insertions(+), 105 deletions(-) diff --git a/crates/servicepoint_binding_c/src/command.rs b/crates/servicepoint_binding_c/src/command.rs index 4e5b45b..d273437 100644 --- a/crates/servicepoint_binding_c/src/command.rs +++ b/crates/servicepoint_binding_c/src/command.rs @@ -4,7 +4,7 @@ use std::ptr::null_mut; -use servicepoint::{Brightness, Origin}; +use servicepoint::{Brightness, Command, Origin}; use crate::{ SPBitVec, SPBrightnessGrid, SPCompressionCode, SPCp437Grid, SPPacket, @@ -15,7 +15,7 @@ use crate::{ /// /// This struct and associated functions implement the UDP protocol for the display. /// -/// To send a [SPCommand], use a `SPConnection`. +/// To send a [SPCommand], use a [SPConnection]. /// /// # Examples /// @@ -31,18 +31,22 @@ impl Clone for SPCommand { } } -/// Tries to turn a `SPPacket` into a [SPCommand]. +/// Tries to turn a [SPPacket] into a [SPCommand]. /// /// The packet is deallocated in the process. /// -/// Returns: pointer to new [SPCommand] instance or NULL +/// Returns: pointer to new [SPCommand] instance or NULL if parsing failed. +/// +/// # Panics +/// +/// - when `packet` is NULL /// /// # Safety /// /// The caller has to make sure that: /// -/// - `SPPacket` points to a valid instance of `SPPacket` -/// - `SPPacket` is not used concurrently or after this call +/// - [SPPacket] points to a valid instance of [SPPacket] +/// - [SPPacket] is not used concurrently or after this call /// - the result is checked for NULL /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or /// by explicitly calling `sp_command_free`. @@ -59,6 +63,12 @@ pub unsafe extern "C" fn sp_command_try_from_packet( /// Clones a [SPCommand] instance. /// +/// returns: new [SPCommand] instance. Will never return NULL. +/// +/// # Panics +/// +/// - when `command` is NULL +/// /// # Safety /// /// The caller has to make sure that: @@ -71,14 +81,17 @@ pub unsafe extern "C" fn sp_command_try_from_packet( pub unsafe extern "C" fn sp_command_clone( command: *const SPCommand, ) -> *mut SPCommand { - Box::into_raw(Box::new((*command).clone())) + assert!(!command.is_null()); + let result = Box::into_raw(Box::new((*command).clone())); + assert!(!result.is_null()); + result } /// Set all pixels to the off state. /// /// Does not affect brightness. /// -/// Returns: a new `Command::Clear` instance. Will never return NULL. +/// Returns: a new [Command::Clear] instance. Will never return NULL. /// /// # Examples /// @@ -94,14 +107,16 @@ pub unsafe extern "C" fn sp_command_clone( /// by explicitly calling `sp_command_free`. #[no_mangle] pub unsafe extern "C" fn sp_command_clear() -> *mut SPCommand { - Box::into_raw(Box::new(SPCommand(servicepoint::Command::Clear))) + let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::Clear))); + assert!(!result.is_null()); + result } /// Kills the udp daemon on the display, which usually results in a restart. /// /// Please do not send this in your normal program flow. /// -/// Returns: a new `Command::HardReset` instance. Will never return NULL. +/// Returns: a new [Command::HardReset] instance. Will never return NULL. /// /// # Safety /// @@ -111,7 +126,9 @@ pub unsafe extern "C" fn sp_command_clear() -> *mut SPCommand { /// by explicitly calling `sp_command_free`. #[no_mangle] pub unsafe extern "C" fn sp_command_hard_reset() -> *mut SPCommand { - Box::into_raw(Box::new(SPCommand(servicepoint::Command::HardReset))) + let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::HardReset))); + assert!(!result.is_null()); + result } /// A yet-to-be-tested command. @@ -126,12 +143,14 @@ pub unsafe extern "C" fn sp_command_hard_reset() -> *mut SPCommand { /// by explicitly calling `sp_command_free`. #[no_mangle] pub unsafe extern "C" fn sp_command_fade_out() -> *mut SPCommand { - Box::into_raw(Box::new(SPCommand(servicepoint::Command::FadeOut))) + let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::FadeOut))); + assert!(!result.is_null()); + result } /// Set the brightness of all tiles to the same value. /// -/// Returns: a new `Command::Brightness` instance. Will never return NULL. +/// Returns: a new [Command::Brightness] instance. Will never return NULL. /// /// # Panics /// @@ -149,16 +168,22 @@ pub unsafe extern "C" fn sp_command_brightness( ) -> *mut SPCommand { let brightness = Brightness::try_from(brightness).expect("invalid brightness"); - Box::into_raw(Box::new(SPCommand(servicepoint::Command::Brightness( + let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::Brightness( brightness, - )))) + )))); + assert!(!result.is_null()); + result } /// Set the brightness of individual tiles in a rectangular area of the display. /// /// 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. +/// +/// # Panics +/// +/// - when `grid` is NULL /// /// # Safety /// @@ -174,11 +199,14 @@ pub unsafe extern "C" fn sp_command_char_brightness( y: usize, grid: *mut SPBrightnessGrid, ) -> *mut SPCommand { + assert!(!grid.is_null()); let byte_grid = *Box::from_raw(grid); - Box::into_raw(Box::new(SPCommand(servicepoint::Command::CharBrightness( + let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::CharBrightness( Origin::new(x, y), byte_grid.0, - )))) + )))); + assert!(!result.is_null()); + result } /// Set pixel data starting at the pixel offset on screen. @@ -190,7 +218,12 @@ pub unsafe extern "C" fn sp_command_char_brightness( /// /// The passed [SPBitVec] gets consumed. /// -/// Returns: a new `Command::BitmapLinear` instance. Will never return NULL. +/// Returns: a new [Command::BitmapLinear] instance. Will never return NULL. +/// +/// # Panics +/// +/// - when `bit_vec` is null +/// - when `compression_code` is not a valid value /// /// # Safety /// @@ -207,12 +240,15 @@ pub unsafe extern "C" fn sp_command_bitmap_linear( bit_vec: *mut SPBitVec, compression: SPCompressionCode, ) -> *mut SPCommand { + assert!(!bit_vec.is_null()); let bit_vec = *Box::from_raw(bit_vec); - Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinear( + let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinear( offset, bit_vec.into(), compression.try_into().expect("invalid compression code"), - )))) + )))); + assert!(!result.is_null()); + result } /// Set pixel data according to an and-mask starting at the offset. @@ -224,7 +260,12 @@ pub unsafe extern "C" fn sp_command_bitmap_linear( /// /// The passed [SPBitVec] gets consumed. /// -/// Returns: a new `Command::BitmapLinearAnd` instance. Will never return NULL. +/// Returns: a new [Command::BitmapLinearAnd] instance. Will never return NULL. +/// +/// # Panics +/// +/// - when `bit_vec` is null +/// - when `compression_code` is not a valid value /// /// # Safety /// @@ -241,12 +282,15 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_and( bit_vec: *mut SPBitVec, compression: SPCompressionCode, ) -> *mut SPCommand { + assert!(!bit_vec.is_null()); let bit_vec = *Box::from_raw(bit_vec); - Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinearAnd( + let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinearAnd( offset, bit_vec.into(), compression.try_into().expect("invalid compression code"), - )))) + )))); + assert!(!result.is_null()); + result } /// Set pixel data according to an or-mask starting at the offset. @@ -258,7 +302,12 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_and( /// /// The passed [SPBitVec] gets consumed. /// -/// Returns: a new `Command::BitmapLinearOr` instance. Will never return NULL. +/// Returns: a new [Command::BitmapLinearOr] instance. Will never return NULL. +/// +/// # Panics +/// +/// - when `bit_vec` is null +/// - when `compression_code` is not a valid value /// /// # Safety /// @@ -275,12 +324,15 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_or( bit_vec: *mut SPBitVec, compression: SPCompressionCode, ) -> *mut SPCommand { + assert!(!bit_vec.is_null()); let bit_vec = *Box::from_raw(bit_vec); - Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinearOr( + let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinearOr( offset, bit_vec.into(), compression.try_into().expect("invalid compression code"), - )))) + )))); + assert!(!result.is_null()); + result } /// Set pixel data according to a xor-mask starting at the offset. @@ -292,7 +344,12 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_or( /// /// The passed [SPBitVec] gets consumed. /// -/// Returns: a new `Command::BitmapLinearXor` instance. Will never return NULL. +/// Returns: a new [Command::BitmapLinearXor] instance. Will never return NULL. +/// +/// # Panics +/// +/// - when `bit_vec` is null +/// - when `compression_code` is not a valid value /// /// # Safety /// @@ -309,30 +366,32 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_xor( bit_vec: *mut SPBitVec, compression: SPCompressionCode, ) -> *mut SPCommand { + assert!(!bit_vec.is_null()); let bit_vec = *Box::from_raw(bit_vec); - Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinearXor( + let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinearXor( offset, bit_vec.into(), compression.try_into().expect("invalid compression code"), - )))) + )))); + assert!(!result.is_null()); + result } /// Show text on the screen. /// -///
-/// The library does not currently convert between UTF-8 and CP-437. -/// Because Rust expects UTF-8 strings, it might be necessary to only send ASCII for now. -///
+/// The passed [SPCp437Grid] gets consumed. /// -/// The passed `SPCp437Grid` gets consumed./// +/// Returns: a new [Command::Cp437Data] instance. Will never return NULL. /// -/// Returns: a new `Command::Cp437Data` instance. Will never return NULL. +/// # Panics +/// +/// - when `grid` is null /// /// # Safety /// /// The caller has to make sure that: /// -/// - `grid` points to a valid instance of `SPCp437Grid` +/// - `grid` points to a valid instance of [SPCp437Grid] /// - `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`. @@ -342,24 +401,32 @@ pub unsafe extern "C" fn sp_command_cp437_data( y: usize, grid: *mut SPCp437Grid, ) -> *mut SPCommand { + assert!(!grid.is_null()); let grid = *Box::from_raw(grid); - Box::into_raw(Box::new(SPCommand(servicepoint::Command::Cp437Data( + let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::Cp437Data( Origin::new(x, y), grid.0, - )))) + )))); + assert!(!result.is_null()); + result } /// Sets a window of pixels to the specified values. /// -/// The passed `SPPixelGrid` gets consumed. +/// The passed [SPPixelGrid] gets consumed. /// -/// Returns: a new `Command::BitmapLinearWin` instance. Will never return NULL. +/// Returns: a new [Command::BitmapLinearWin] instance. Will never return NULL. +/// +/// # Panics +/// +/// - when `pixel_grid` is null +/// - when `compression_code` is not a valid value /// /// # Safety /// /// The caller has to make sure that: /// -/// - `pixel_grid` points to a valid instance of `SPPixelGrid` +/// - `pixel_grid` points to a valid instance of [SPPixelGrid] /// - `pixel_grid` is not used concurrently or after this call /// - `compression` matches one of the allowed enum values /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or @@ -371,14 +438,17 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_win( pixel_grid: *mut SPPixelGrid, compression_code: SPCompressionCode, ) -> *mut SPCommand { + assert!(!pixel_grid.is_null()); let byte_grid = (*Box::from_raw(pixel_grid)).0; - Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinearWin( + let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinearWin( Origin::new(x, y), byte_grid, compression_code .try_into() .expect("invalid compression code"), - )))) + )))); + assert!(!result.is_null()); + result } /// Deallocates a [SPCommand]. @@ -390,14 +460,19 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_win( /// sp_command_free(c); /// ``` /// +/// # Panics +/// +/// - when `command` is NULL +/// /// # Safety /// /// The caller has to make sure that: /// /// - `command` points to a valid [SPCommand] /// - `command` is not used concurrently or after this call -/// - `command` was not passed to another consuming function, e.g. to create a `SPPacket` +/// - `command` was not passed to another consuming function, e.g. to create a [SPPacket] #[no_mangle] pub unsafe extern "C" fn sp_command_free(command: *mut SPCommand) { + assert!(!command.is_null()); _ = Box::from_raw(command); } diff --git a/crates/servicepoint_binding_c/src/connection.rs b/crates/servicepoint_binding_c/src/connection.rs index ee630a9..95940f8 100644 --- a/crates/servicepoint_binding_c/src/connection.rs +++ b/crates/servicepoint_binding_c/src/connection.rs @@ -18,7 +18,7 @@ use crate::{SPCommand, SPPacket}; /// ``` pub struct SPConnection(pub(crate) servicepoint::Connection); -/// Creates a new instance of `SPConnection`. +/// Creates a new instance of [SPConnection]. /// /// returns: NULL if connection fails, or connected instance /// @@ -45,7 +45,7 @@ pub unsafe extern "C" fn sp_connection_open( Box::into_raw(Box::new(SPConnection(connection))) } -/// Sends a `SPPacket` to the display using the `SPConnection`. +/// Sends a [SPPacket] to the display using the [SPConnection]. /// /// The passed `packet` gets consumed. /// @@ -55,8 +55,8 @@ pub unsafe extern "C" fn sp_connection_open( /// /// The caller has to make sure that: /// -/// - `connection` points to a valid instance of `SPConnection` -/// - `packet` points to a valid instance of `SPPacket` +/// - `connection` points to a valid instance of [SPConnection] +/// - `packet` points to a valid instance of [SPPacket] /// - `packet` is not used concurrently or after this call #[no_mangle] pub unsafe extern "C" fn sp_connection_send_packet( @@ -77,8 +77,8 @@ pub unsafe extern "C" fn sp_connection_send_packet( /// /// The caller has to make sure that: /// -/// - `connection` points to a valid instance of `SPConnection` -/// - `command` points to a valid instance of `SPPacket` +/// - `connection` points to a valid instance of [SPConnection] +/// - `command` points to a valid instance of [SPPacket] /// - `command` is not used concurrently or after this call #[no_mangle] pub unsafe extern "C" fn sp_connection_send_command( @@ -89,13 +89,19 @@ pub unsafe extern "C" fn sp_connection_send_command( (*connection).0.send(command).is_ok() } -/// Closes and deallocates a `SPConnection`. +/// Closes and deallocates a [SPConnection]. +/// +/// # Panics +/// +/// # Panics +/// +/// - when `connection` is NULL /// /// # Safety /// /// The caller has to make sure that: /// -/// - `connection` points to a valid `SPConnection` +/// - `connection` points to a valid [SPConnection] /// - `connection` is not used concurrently or after this call #[no_mangle] pub unsafe extern "C" fn sp_connection_free(connection: *mut SPConnection) { diff --git a/crates/servicepoint_binding_c/src/cp437_grid.rs b/crates/servicepoint_binding_c/src/cp437_grid.rs index 38d4af0..98b1927 100644 --- a/crates/servicepoint_binding_c/src/cp437_grid.rs +++ b/crates/servicepoint_binding_c/src/cp437_grid.rs @@ -1,4 +1,4 @@ -//! C functions for interacting with `SPCp437Grid`s +//! C functions for interacting with [SPCp437Grid]s //! //! prefix `sp_cp437_grid_` @@ -25,9 +25,9 @@ impl Clone for SPCp437Grid { } } -/// Creates a new `SPCp437Grid` with the specified dimensions. +/// Creates a new [SPCp437Grid] with the specified dimensions. /// -/// returns: `SPCp437Grid` initialized to 0. +/// returns: [SPCp437Grid] initialized to 0. /// /// # Safety /// @@ -45,7 +45,7 @@ pub unsafe extern "C" fn sp_cp437_grid_new( )))) } -/// Loads a `SPCp437Grid` with the specified dimensions from the provided data. +/// Loads a [SPCp437Grid] with the specified dimensions from the provided data. /// /// Will never return NULL. /// @@ -74,7 +74,7 @@ pub unsafe extern "C" fn sp_cp437_grid_load( )))) } -/// Clones a `SPCp437Grid`. +/// Clones a [SPCp437Grid]. /// /// Will never return NULL. /// @@ -82,7 +82,7 @@ pub unsafe extern "C" fn sp_cp437_grid_load( /// /// The caller has to make sure that: /// -/// - `cp437_grid` points to a valid `SPCp437Grid` +/// - `cp437_grid` points to a valid [SPCp437Grid] /// - `cp437_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_cp437_grid_free`. @@ -93,13 +93,13 @@ pub unsafe extern "C" fn sp_cp437_grid_clone( Box::into_raw(Box::new((*cp437_grid).clone())) } -/// Deallocates a `SPCp437Grid`. +/// Deallocates a [SPCp437Grid]. /// /// # Safety /// /// The caller has to make sure that: /// -/// - `cp437_grid` points to a valid `SPCp437Grid` +/// - `cp437_grid` points to a valid [SPCp437Grid] /// - `cp437_grid` is not used concurrently or after cp437_grid call /// - `cp437_grid` was not passed to another consuming function, e.g. to create a [SPCommand] #[no_mangle] @@ -122,7 +122,7 @@ pub unsafe extern "C" fn sp_cp437_grid_free(cp437_grid: *mut SPCp437Grid) { /// /// The caller has to make sure that: /// -/// - `cp437_grid` points to a valid `SPCp437Grid` +/// - `cp437_grid` points to a valid [SPCp437Grid] /// - `cp437_grid` is not written to concurrently #[no_mangle] pub unsafe extern "C" fn sp_cp437_grid_get( @@ -133,7 +133,7 @@ pub unsafe extern "C" fn sp_cp437_grid_get( (*cp437_grid).0.get(x, y) } -/// Sets the value of the specified position in the `SPCp437Grid`. +/// Sets the value of the specified position in the [SPCp437Grid]. /// /// # Arguments /// @@ -163,7 +163,7 @@ pub unsafe extern "C" fn sp_cp437_grid_set( (*cp437_grid).0.set(x, y, value); } -/// Sets the value of all cells in the `SPCp437Grid`. +/// Sets the value of all cells in the [SPCp437Grid]. /// /// # Arguments /// @@ -174,7 +174,7 @@ pub unsafe extern "C" fn sp_cp437_grid_set( /// /// The caller has to make sure that: /// -/// - `cp437_grid` points to a valid `SPCp437Grid` +/// - `cp437_grid` points to a valid [SPCp437Grid] /// - `cp437_grid` is not written to or read from concurrently #[no_mangle] pub unsafe extern "C" fn sp_cp437_grid_fill( @@ -184,7 +184,7 @@ pub unsafe extern "C" fn sp_cp437_grid_fill( (*cp437_grid).0.fill(value); } -/// Gets the width of the `SPCp437Grid` instance. +/// Gets the width of the [SPCp437Grid] instance. /// /// # Arguments /// @@ -194,7 +194,7 @@ pub unsafe extern "C" fn sp_cp437_grid_fill( /// /// The caller has to make sure that: /// -/// - `cp437_grid` points to a valid `SPCp437Grid` +/// - `cp437_grid` points to a valid [SPCp437Grid] #[no_mangle] pub unsafe extern "C" fn sp_cp437_grid_width( cp437_grid: *const SPCp437Grid, @@ -202,7 +202,7 @@ pub unsafe extern "C" fn sp_cp437_grid_width( (*cp437_grid).0.width() } -/// Gets the height of the `SPCp437Grid` instance. +/// Gets the height of the [SPCp437Grid] instance. /// /// # Arguments /// @@ -212,7 +212,7 @@ pub unsafe extern "C" fn sp_cp437_grid_width( /// /// The caller has to make sure that: /// -/// - `cp437_grid` points to a valid `SPCp437Grid` +/// - `cp437_grid` points to a valid [SPCp437Grid] #[no_mangle] pub unsafe extern "C" fn sp_cp437_grid_height( cp437_grid: *const SPCp437Grid, @@ -220,7 +220,7 @@ pub unsafe extern "C" fn sp_cp437_grid_height( (*cp437_grid).0.height() } -/// Gets an unsafe reference to the data of the `SPCp437Grid` instance. +/// Gets an unsafe reference to the data of the [SPCp437Grid] instance. /// /// Will never return NULL. /// @@ -228,9 +228,9 @@ pub unsafe extern "C" fn sp_cp437_grid_height( /// /// The caller has to make sure that: /// -/// - `cp437_grid` points to a valid `SPCp437Grid` -/// - the returned memory range is never accessed after the passed `SPCp437Grid` has been freed -/// - the returned memory range is never accessed concurrently, either via the `SPCp437Grid` or directly +/// - `cp437_grid` points to a valid [SPCp437Grid] +/// - the returned memory range is never accessed after the passed [SPCp437Grid] has been freed +/// - the returned memory range is never accessed concurrently, either via the [SPCp437Grid] or directly #[no_mangle] pub unsafe extern "C" fn sp_cp437_grid_unsafe_data_ref( cp437_grid: *mut SPCp437Grid, diff --git a/crates/servicepoint_binding_c/src/packet.rs b/crates/servicepoint_binding_c/src/packet.rs index d8a0302..ac27747 100644 --- a/crates/servicepoint_binding_c/src/packet.rs +++ b/crates/servicepoint_binding_c/src/packet.rs @@ -1,4 +1,4 @@ -//! C functions for interacting with `SPPacket`s +//! C functions for interacting with [SPPacket]s //! //! prefix `sp_packet_` @@ -9,7 +9,7 @@ use crate::SPCommand; /// The raw packet pub struct SPPacket(pub(crate) servicepoint::packet::Packet); -/// Turns a [SPCommand] into a `SPPacket`. +/// Turns a [SPCommand] into a [SPPacket]. /// The [SPCommand] gets consumed. /// /// Will never return NULL. @@ -20,7 +20,7 @@ pub struct SPPacket(pub(crate) servicepoint::packet::Packet); /// /// - [SPCommand] points to a valid instance of [SPCommand] /// - [SPCommand] is not used concurrently or after this call -/// - the returned `SPPacket` instance is freed in some way, either by using a consuming function or +/// - the returned [SPPacket] instance is freed in some way, either by using a consuming function or /// by explicitly calling `sp_packet_free`. #[no_mangle] pub unsafe extern "C" fn sp_packet_from_command( @@ -31,7 +31,7 @@ pub unsafe extern "C" fn sp_packet_from_command( Box::into_raw(Box::new(packet)) } -/// 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. /// /// returns: NULL in case of an error, pointer to the allocated packet otherwise /// @@ -41,7 +41,7 @@ pub unsafe extern "C" fn sp_packet_from_command( /// /// - `data` points to a valid memory region of at least `length` bytes /// - `data` is not written to concurrently -/// - the returned `SPPacket` instance is freed in some way, either by using a consuming function or +/// - the returned [SPPacket] instance is freed in some way, either by using a consuming function or /// by explicitly calling `sp_packet_free`. #[no_mangle] pub unsafe extern "C" fn sp_packet_try_load( @@ -55,7 +55,7 @@ pub unsafe extern "C" fn sp_packet_try_load( } } -/// Clones a `SPPacket`. +/// Clones a [SPPacket]. /// /// Will never return NULL. /// @@ -63,7 +63,7 @@ pub unsafe extern "C" fn sp_packet_try_load( /// /// The caller has to make sure that: /// -/// - `packet` points to a valid `SPPacket` +/// - `packet` points to a valid [SPPacket] /// - `packet` is not written to concurrently /// - the returned instance is freed in some way, either by using a consuming function or /// by explicitly calling `sp_packet_free`. @@ -74,13 +74,13 @@ pub unsafe extern "C" fn sp_packet_clone( Box::into_raw(Box::new(SPPacket((*packet).0.clone()))) } -/// Deallocates a `SPPacket`. +/// Deallocates a [SPPacket]. /// /// # Safety /// /// The caller has to make sure that: /// -/// - `packet` points to a valid `SPPacket` +/// - `packet` points to a valid [SPPacket] /// - `packet` is not used concurrently or after this call #[no_mangle] pub unsafe extern "C" fn sp_packet_free(packet: *mut SPPacket) { diff --git a/crates/servicepoint_binding_c/src/pixel_grid.rs b/crates/servicepoint_binding_c/src/pixel_grid.rs index e032d50..6592ae5 100644 --- a/crates/servicepoint_binding_c/src/pixel_grid.rs +++ b/crates/servicepoint_binding_c/src/pixel_grid.rs @@ -1,4 +1,4 @@ -//! C functions for interacting with `SPPixelGrid`s +//! C functions for interacting with [SPPixelGrid]s //! //! prefix `sp_pixel_grid_` @@ -18,14 +18,14 @@ use crate::byte_slice::SPByteSlice; /// ``` pub struct SPPixelGrid(pub(crate) servicepoint::PixelGrid); -/// Creates a new `SPPixelGrid` with the specified dimensions. +/// Creates a new [SPPixelGrid] with the specified dimensions. /// /// # Arguments /// /// - `width`: size in pixels in x-direction /// - `height`: size in pixels in y-direction /// -/// returns: `SPPixelGrid` initialized to all pixels off. Will never return NULL. +/// returns: [SPPixelGrid] initialized to all pixels off. Will never return NULL. /// /// # Panics /// @@ -47,14 +47,14 @@ pub unsafe extern "C" fn sp_pixel_grid_new( )))) } -/// Loads a `SPPixelGrid` with the specified dimensions from the provided data. +/// Loads a [SPPixelGrid] with the specified dimensions from the provided data. /// /// # Arguments /// /// - `width`: size in pixels in x-direction /// - `height`: size in pixels in y-direction /// -/// returns: `SPPixelGrid` that contains a copy of the provided data. Will never return NULL. +/// returns: [SPPixelGrid] that contains a copy of the provided data. Will never return NULL. /// /// # Panics /// @@ -81,7 +81,7 @@ pub unsafe extern "C" fn sp_pixel_grid_load( )))) } -/// Clones a `SPPixelGrid`. +/// Clones a [SPPixelGrid]. /// /// Will never return NULL. /// @@ -89,7 +89,7 @@ pub unsafe extern "C" fn sp_pixel_grid_load( /// /// The caller has to make sure that: /// -/// - `pixel_grid` points to a valid `SPPixelGrid` +/// - `pixel_grid` points to a valid [SPPixelGrid] /// - `pixel_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_pixel_grid_free`. @@ -100,13 +100,13 @@ pub unsafe extern "C" fn sp_pixel_grid_clone( Box::into_raw(Box::new(SPPixelGrid((*pixel_grid).0.clone()))) } -/// Deallocates a `SPPixelGrid`. +/// Deallocates a [SPPixelGrid]. /// /// # Safety /// /// The caller has to make sure that: /// -/// - `pixel_grid` points to a valid `SPPixelGrid` +/// - `pixel_grid` points to a valid [SPPixelGrid] /// - `pixel_grid` is not used concurrently or after pixel_grid call /// - `pixel_grid` was not passed to another consuming function, e.g. to create a [SPCommand] #[no_mangle] @@ -114,7 +114,7 @@ pub unsafe extern "C" fn sp_pixel_grid_free(pixel_grid: *mut SPPixelGrid) { _ = Box::from_raw(pixel_grid); } -/// Gets the current value at the specified position in the `SPPixelGrid`. +/// Gets the current value at the specified position in the [SPPixelGrid]. /// /// # Arguments /// @@ -129,7 +129,7 @@ pub unsafe extern "C" fn sp_pixel_grid_free(pixel_grid: *mut SPPixelGrid) { /// /// The caller has to make sure that: /// -/// - `pixel_grid` points to a valid `SPPixelGrid` +/// - `pixel_grid` points to a valid [SPPixelGrid] /// - `pixel_grid` is not written to concurrently #[no_mangle] pub unsafe extern "C" fn sp_pixel_grid_get( @@ -140,7 +140,7 @@ pub unsafe extern "C" fn sp_pixel_grid_get( (*pixel_grid).0.get(x, y) } -/// Sets the value of the specified position in the `SPPixelGrid`. +/// Sets the value of the specified position in the [SPPixelGrid]. /// /// # Arguments /// @@ -158,7 +158,7 @@ pub unsafe extern "C" fn sp_pixel_grid_get( /// /// The caller has to make sure that: /// -/// - `pixel_grid` points to a valid `SPPixelGrid` +/// - `pixel_grid` points to a valid [SPPixelGrid] /// - `pixel_grid` is not written to or read from concurrently #[no_mangle] pub unsafe extern "C" fn sp_pixel_grid_set( @@ -170,7 +170,7 @@ pub unsafe extern "C" fn sp_pixel_grid_set( (*pixel_grid).0.set(x, y, value); } -/// Sets the state of all pixels in the `SPPixelGrid`. +/// Sets the state of all pixels in the [SPPixelGrid]. /// /// # Arguments /// @@ -181,7 +181,7 @@ pub unsafe extern "C" fn sp_pixel_grid_set( /// /// The caller has to make sure that: /// -/// - `pixel_grid` points to a valid `SPPixelGrid` +/// - `pixel_grid` points to a valid [SPPixelGrid] /// - `pixel_grid` is not written to or read from concurrently #[no_mangle] pub unsafe extern "C" fn sp_pixel_grid_fill( @@ -191,7 +191,7 @@ pub unsafe extern "C" fn sp_pixel_grid_fill( (*pixel_grid).0.fill(value); } -/// Gets the width in pixels of the `SPPixelGrid` instance. +/// Gets the width in pixels of the [SPPixelGrid] instance. /// /// # Arguments /// @@ -201,7 +201,7 @@ pub unsafe extern "C" fn sp_pixel_grid_fill( /// /// The caller has to make sure that: /// -/// - `pixel_grid` points to a valid `SPPixelGrid` +/// - `pixel_grid` points to a valid [SPPixelGrid] #[no_mangle] pub unsafe extern "C" fn sp_pixel_grid_width( pixel_grid: *const SPPixelGrid, @@ -209,7 +209,7 @@ pub unsafe extern "C" fn sp_pixel_grid_width( (*pixel_grid).0.width() } -/// Gets the height in pixels of the `SPPixelGrid` instance. +/// Gets the height in pixels of the [SPPixelGrid] instance. /// /// # Arguments /// @@ -219,7 +219,7 @@ pub unsafe extern "C" fn sp_pixel_grid_width( /// /// The caller has to make sure that: /// -/// - `pixel_grid` points to a valid `SPPixelGrid` +/// - `pixel_grid` points to a valid [SPPixelGrid] #[no_mangle] pub unsafe extern "C" fn sp_pixel_grid_height( pixel_grid: *const SPPixelGrid, @@ -227,15 +227,15 @@ pub unsafe extern "C" fn sp_pixel_grid_height( (*pixel_grid).0.height() } -/// Gets an unsafe reference to the data of the `SPPixelGrid` instance. +/// Gets an unsafe reference to the data of the [SPPixelGrid] instance. /// /// ## Safety /// /// The caller has to make sure that: /// -/// - `pixel_grid` points to a valid `SPPixelGrid` -/// - the returned memory range is never accessed after the passed `SPPixelGrid` has been freed -/// - the returned memory range is never accessed concurrently, either via the `SPPixelGrid` or directly +/// - `pixel_grid` points to a valid [SPPixelGrid] +/// - the returned memory range is never accessed after the passed [SPPixelGrid] has been freed +/// - the returned memory range is never accessed concurrently, either via the [SPPixelGrid] or directly #[no_mangle] pub unsafe extern "C" fn sp_pixel_grid_unsafe_data_ref( pixel_grid: *mut SPPixelGrid, From f2ff07d9d9ba3fbad329eab5dfbebf5717278a7d Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Mon, 14 Oct 2024 22:01:45 +0200 Subject: [PATCH 11/27] add NULL checks - rest --- .../servicepoint_binding_c/src/connection.rs | 24 ++++++-- .../servicepoint_binding_c/src/cp437_grid.rs | 59 ++++++++++++++++--- crates/servicepoint_binding_c/src/packet.rs | 28 ++++++++- .../servicepoint_binding_c/src/pixel_grid.rs | 58 +++++++++++++++--- 4 files changed, 145 insertions(+), 24 deletions(-) diff --git a/crates/servicepoint_binding_c/src/connection.rs b/crates/servicepoint_binding_c/src/connection.rs index 95940f8..3f54438 100644 --- a/crates/servicepoint_binding_c/src/connection.rs +++ b/crates/servicepoint_binding_c/src/connection.rs @@ -1,4 +1,4 @@ -//! C functions for interacting with `SPConnection`s +//! C functions for interacting with [SPConnection]s //! //! prefix `sp_connection_` @@ -24,7 +24,7 @@ pub struct SPConnection(pub(crate) servicepoint::Connection); /// /// # Panics /// -/// Bad string encoding +/// - when `host` is null or an invalid host /// /// # Safety /// @@ -36,6 +36,7 @@ pub struct SPConnection(pub(crate) servicepoint::Connection); pub unsafe extern "C" fn sp_connection_open( host: *const c_char, ) -> *mut SPConnection { + assert!(!host.is_null()); let host = CStr::from_ptr(host).to_str().expect("Bad encoding"); let connection = match servicepoint::Connection::open(host) { Err(_) => return null_mut(), @@ -51,6 +52,11 @@ pub unsafe extern "C" fn sp_connection_open( /// /// returns: true in case of success /// +/// # Panics +/// +/// - when `connection` is NULL +/// - when `packet` is NULL +/// /// # Safety /// /// The caller has to make sure that: @@ -63,16 +69,23 @@ pub unsafe extern "C" fn sp_connection_send_packet( connection: *const SPConnection, packet: *mut SPPacket, ) -> bool { + assert!(!connection.is_null()); + assert!(!packet.is_null()); let packet = Box::from_raw(packet); (*connection).0.send((*packet).0).is_ok() } -/// Sends a [SPCommand] to the display using the `SPConnection`. +/// Sends a [SPCommand] to the display using the [SPConnection]. /// /// The passed `command` gets consumed. /// /// returns: true in case of success /// +/// # Panics +/// +/// - when `connection` is NULL +/// - when `command` is NULL +/// /// # Safety /// /// The caller has to make sure that: @@ -85,6 +98,8 @@ pub unsafe extern "C" fn sp_connection_send_command( connection: *const SPConnection, command: *mut SPCommand, ) -> bool { + assert!(!connection.is_null()); + assert!(!command.is_null()); let command = (*Box::from_raw(command)).0; (*connection).0.send(command).is_ok() } @@ -93,8 +108,6 @@ pub unsafe extern "C" fn sp_connection_send_command( /// /// # Panics /// -/// # Panics -/// /// - when `connection` is NULL /// /// # Safety @@ -105,5 +118,6 @@ pub unsafe extern "C" fn sp_connection_send_command( /// - `connection` is not used concurrently or after this call #[no_mangle] pub unsafe extern "C" fn sp_connection_free(connection: *mut SPConnection) { + assert!(!connection.is_null()); _ = Box::from_raw(connection); } diff --git a/crates/servicepoint_binding_c/src/cp437_grid.rs b/crates/servicepoint_binding_c/src/cp437_grid.rs index 98b1927..791c594 100644 --- a/crates/servicepoint_binding_c/src/cp437_grid.rs +++ b/crates/servicepoint_binding_c/src/cp437_grid.rs @@ -27,7 +27,7 @@ impl Clone for SPCp437Grid { /// Creates a new [SPCp437Grid] with the specified dimensions. /// -/// returns: [SPCp437Grid] initialized to 0. +/// returns: [SPCp437Grid] initialized to 0. Will never return NULL. /// /// # Safety /// @@ -40,9 +40,11 @@ pub unsafe extern "C" fn sp_cp437_grid_new( width: usize, height: usize, ) -> *mut SPCp437Grid { - Box::into_raw(Box::new(SPCp437Grid(servicepoint::Cp437Grid::new( + let result = Box::into_raw(Box::new(SPCp437Grid(servicepoint::Cp437Grid::new( width, height, - )))) + )))); + assert!(!result.is_null()); + result } /// Loads a [SPCp437Grid] with the specified dimensions from the provided data. @@ -51,7 +53,8 @@ pub unsafe extern "C" fn sp_cp437_grid_new( /// /// # 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 /// @@ -68,16 +71,23 @@ pub unsafe extern "C" fn sp_cp437_grid_load( data: *const u8, data_length: usize, ) -> *mut SPCp437Grid { + assert!(data.is_null()); let data = std::slice::from_raw_parts(data, data_length); - Box::into_raw(Box::new(SPCp437Grid(servicepoint::Cp437Grid::load( + let result = Box::into_raw(Box::new(SPCp437Grid(servicepoint::Cp437Grid::load( width, height, data, - )))) + )))); + assert!(!result.is_null()); + result } /// Clones a [SPCp437Grid]. /// /// Will never return NULL. /// +/// # Panics +/// +/// - when `cp437_grid` is NULL +/// /// # Safety /// /// The caller has to make sure that: @@ -90,11 +100,18 @@ pub unsafe extern "C" fn sp_cp437_grid_load( pub unsafe extern "C" fn sp_cp437_grid_clone( cp437_grid: *const SPCp437Grid, ) -> *mut SPCp437Grid { - Box::into_raw(Box::new((*cp437_grid).clone())) + assert!(!cp437_grid.is_null()); + let result = Box::into_raw(Box::new((*cp437_grid).clone())); + assert!(!result.is_null()); + result } /// Deallocates a [SPCp437Grid]. /// +/// # Panics +/// +/// - when `cp437_grid` is NULL +/// /// # Safety /// /// The caller has to make sure that: @@ -104,6 +121,7 @@ pub unsafe extern "C" fn sp_cp437_grid_clone( /// - `cp437_grid` was not passed to another consuming function, e.g. to create a [SPCommand] #[no_mangle] pub unsafe extern "C" fn sp_cp437_grid_free(cp437_grid: *mut SPCp437Grid) { + assert!(!cp437_grid.is_null()); _ = Box::from_raw(cp437_grid); } @@ -116,7 +134,8 @@ pub unsafe extern "C" fn sp_cp437_grid_free(cp437_grid: *mut SPCp437Grid) { /// /// # Panics /// -/// When accessing `x` or `y` out of bounds. +/// - when `cp437_grid` is NULL +/// - when accessing `x` or `y` out of bounds /// /// # Safety /// @@ -130,6 +149,7 @@ pub unsafe extern "C" fn sp_cp437_grid_get( x: usize, y: usize, ) -> u8 { + assert!(!cp437_grid.is_null()); (*cp437_grid).0.get(x, y) } @@ -145,7 +165,8 @@ pub unsafe extern "C" fn sp_cp437_grid_get( /// /// # Panics /// -/// When accessing `x` or `y` out of bounds. +/// - when `cp437_grid` is NULL +/// - when accessing `x` or `y` out of bounds /// /// # Safety /// @@ -160,6 +181,7 @@ pub unsafe extern "C" fn sp_cp437_grid_set( y: usize, value: u8, ) { + assert!(!cp437_grid.is_null()); (*cp437_grid).0.set(x, y, value); } @@ -170,6 +192,10 @@ pub unsafe extern "C" fn sp_cp437_grid_set( /// - `cp437_grid`: instance to write to /// - `value`: the value to set all cells to /// +/// # Panics +/// +/// - when `cp437_grid` is NULL +/// /// # Safety /// /// The caller has to make sure that: @@ -181,6 +207,7 @@ pub unsafe extern "C" fn sp_cp437_grid_fill( cp437_grid: *mut SPCp437Grid, value: u8, ) { + assert!(!cp437_grid.is_null()); (*cp437_grid).0.fill(value); } @@ -190,6 +217,10 @@ pub unsafe extern "C" fn sp_cp437_grid_fill( /// /// - `cp437_grid`: instance to read from /// +/// # Panics +/// +/// - when `cp437_grid` is NULL +/// /// # Safety /// /// The caller has to make sure that: @@ -199,6 +230,7 @@ pub unsafe extern "C" fn sp_cp437_grid_fill( pub unsafe extern "C" fn sp_cp437_grid_width( cp437_grid: *const SPCp437Grid, ) -> usize { + assert!(!cp437_grid.is_null()); (*cp437_grid).0.width() } @@ -208,6 +240,10 @@ pub unsafe extern "C" fn sp_cp437_grid_width( /// /// - `cp437_grid`: instance to read from /// +/// # Panics +/// +/// - when `cp437_grid` is NULL +/// /// # Safety /// /// The caller has to make sure that: @@ -217,6 +253,7 @@ pub unsafe extern "C" fn sp_cp437_grid_width( pub unsafe extern "C" fn sp_cp437_grid_height( cp437_grid: *const SPCp437Grid, ) -> usize { + assert!(!cp437_grid.is_null()); (*cp437_grid).0.height() } @@ -224,6 +261,10 @@ pub unsafe extern "C" fn sp_cp437_grid_height( /// /// Will never return NULL. /// +/// # Panics +/// +/// - when `cp437_grid` is NULL +/// /// ## Safety /// /// The caller has to make sure that: diff --git a/crates/servicepoint_binding_c/src/packet.rs b/crates/servicepoint_binding_c/src/packet.rs index ac27747..f2cffc4 100644 --- a/crates/servicepoint_binding_c/src/packet.rs +++ b/crates/servicepoint_binding_c/src/packet.rs @@ -14,6 +14,10 @@ pub struct SPPacket(pub(crate) servicepoint::packet::Packet); /// /// Will never return NULL. /// +/// # Panics +/// +/// - when `command` is NULL +/// /// # Safety /// /// The caller has to make sure that: @@ -26,15 +30,22 @@ pub struct SPPacket(pub(crate) servicepoint::packet::Packet); pub unsafe extern "C" fn sp_packet_from_command( command: *mut SPCommand, ) -> *mut SPPacket { + assert!(!command.is_null()); let command = *Box::from_raw(command); let packet = SPPacket(command.0.into()); - Box::into_raw(Box::new(packet)) + let result = Box::into_raw(Box::new(packet)); + assert!(!result.is_null()); + result } /// Tries to load a [SPPacket] from the passed array with the specified length. /// /// returns: NULL in case of an error, pointer to the allocated packet otherwise /// +/// # Panics +/// +/// - when `data` is NULL +/// /// # Safety /// /// The caller has to make sure that: @@ -48,6 +59,7 @@ pub unsafe extern "C" fn sp_packet_try_load( data: *const u8, length: usize, ) -> *mut SPPacket { + assert!(!data.is_null()); let data = std::slice::from_raw_parts(data, length); match servicepoint::packet::Packet::try_from(data) { Err(_) => null_mut(), @@ -59,6 +71,10 @@ pub unsafe extern "C" fn sp_packet_try_load( /// /// Will never return NULL. /// +/// # Panics +/// +/// - when `packet` is NULL +/// /// # Safety /// /// The caller has to make sure that: @@ -71,11 +87,18 @@ pub unsafe extern "C" fn sp_packet_try_load( pub unsafe extern "C" fn sp_packet_clone( packet: *const SPPacket, ) -> *mut SPPacket { - Box::into_raw(Box::new(SPPacket((*packet).0.clone()))) + assert!(!packet.is_null()); + let result = Box::into_raw(Box::new(SPPacket((*packet).0.clone()))); + assert!(!result.is_null()); + result } /// Deallocates a [SPPacket]. /// +/// # Panics +/// +/// - when `sp_packet_free` is NULL +/// /// # Safety /// /// The caller has to make sure that: @@ -84,5 +107,6 @@ pub unsafe extern "C" fn sp_packet_clone( /// - `packet` is not used concurrently or after this call #[no_mangle] pub unsafe extern "C" fn sp_packet_free(packet: *mut SPPacket) { + assert!(!packet.is_null()); _ = Box::from_raw(packet) } diff --git a/crates/servicepoint_binding_c/src/pixel_grid.rs b/crates/servicepoint_binding_c/src/pixel_grid.rs index 6592ae5..8e937fc 100644 --- a/crates/servicepoint_binding_c/src/pixel_grid.rs +++ b/crates/servicepoint_binding_c/src/pixel_grid.rs @@ -42,9 +42,11 @@ pub unsafe extern "C" fn sp_pixel_grid_new( width: usize, height: usize, ) -> *mut SPPixelGrid { - Box::into_raw(Box::new(SPPixelGrid(servicepoint::PixelGrid::new( + let result = Box::into_raw(Box::new(SPPixelGrid(servicepoint::PixelGrid::new( width, height, - )))) + )))); + assert!(!result.is_null()); + result } /// Loads a [SPPixelGrid] with the specified dimensions from the provided data. @@ -58,6 +60,7 @@ pub unsafe extern "C" fn sp_pixel_grid_new( /// /// # Panics /// +/// - when `data` is NULL /// - when the dimensions and data size do not match exactly. /// - when the width is not dividable by 8 /// @@ -75,16 +78,23 @@ pub unsafe extern "C" fn sp_pixel_grid_load( data: *const u8, data_length: usize, ) -> *mut SPPixelGrid { + assert!(!data.is_null()); let data = std::slice::from_raw_parts(data, data_length); - Box::into_raw(Box::new(SPPixelGrid(servicepoint::PixelGrid::load( + let result = Box::into_raw(Box::new(SPPixelGrid(servicepoint::PixelGrid::load( width, height, data, - )))) + )))); + assert!(!result.is_null()); + result } /// Clones a [SPPixelGrid]. /// /// Will never return NULL. /// +/// # Panics +/// +/// - when `pixel_grid` is NULL +/// /// # Safety /// /// The caller has to make sure that: @@ -97,11 +107,18 @@ pub unsafe extern "C" fn sp_pixel_grid_load( pub unsafe extern "C" fn sp_pixel_grid_clone( pixel_grid: *const SPPixelGrid, ) -> *mut SPPixelGrid { - Box::into_raw(Box::new(SPPixelGrid((*pixel_grid).0.clone()))) + assert!(!pixel_grid.is_null()); + let result = Box::into_raw(Box::new(SPPixelGrid((*pixel_grid).0.clone()))); + assert!(!result.is_null()); + result } /// Deallocates a [SPPixelGrid]. /// +/// # Panics +/// +/// - when `pixel_grid` is NULL +/// /// # Safety /// /// The caller has to make sure that: @@ -111,6 +128,7 @@ pub unsafe extern "C" fn sp_pixel_grid_clone( /// - `pixel_grid` was not passed to another consuming function, e.g. to create a [SPCommand] #[no_mangle] pub unsafe extern "C" fn sp_pixel_grid_free(pixel_grid: *mut SPPixelGrid) { + assert!(!pixel_grid.is_null()); _ = Box::from_raw(pixel_grid); } @@ -123,7 +141,8 @@ pub unsafe extern "C" fn sp_pixel_grid_free(pixel_grid: *mut SPPixelGrid) { /// /// # Panics /// -/// When accessing `x` or `y` out of bounds. +/// - when `pixel_grid` is NULL +/// - when accessing `x` or `y` out of bounds /// /// # Safety /// @@ -137,6 +156,7 @@ pub unsafe extern "C" fn sp_pixel_grid_get( x: usize, y: usize, ) -> bool { + assert!(!pixel_grid.is_null()); (*pixel_grid).0.get(x, y) } @@ -152,7 +172,8 @@ pub unsafe extern "C" fn sp_pixel_grid_get( /// /// # Panics /// -/// When accessing `x` or `y` out of bounds. +/// - when `pixel_grid` is NULL +/// - when accessing `x` or `y` out of bounds /// /// # Safety /// @@ -167,6 +188,7 @@ pub unsafe extern "C" fn sp_pixel_grid_set( y: usize, value: bool, ) { + assert!(!pixel_grid.is_null()); (*pixel_grid).0.set(x, y, value); } @@ -177,6 +199,10 @@ pub unsafe extern "C" fn sp_pixel_grid_set( /// - `pixel_grid`: instance to write to /// - `value`: the value to set all pixels to /// +/// # Panics +/// +/// - when `pixel_grid` is NULL +/// /// # Safety /// /// The caller has to make sure that: @@ -188,6 +214,7 @@ pub unsafe extern "C" fn sp_pixel_grid_fill( pixel_grid: *mut SPPixelGrid, value: bool, ) { + assert!(!pixel_grid.is_null()); (*pixel_grid).0.fill(value); } @@ -197,6 +224,10 @@ pub unsafe extern "C" fn sp_pixel_grid_fill( /// /// - `pixel_grid`: instance to read from /// +/// # Panics +/// +/// - when `pixel_grid` is NULL +/// /// # Safety /// /// The caller has to make sure that: @@ -206,6 +237,7 @@ pub unsafe extern "C" fn sp_pixel_grid_fill( pub unsafe extern "C" fn sp_pixel_grid_width( pixel_grid: *const SPPixelGrid, ) -> usize { + assert!(!pixel_grid.is_null()); (*pixel_grid).0.width() } @@ -215,6 +247,10 @@ pub unsafe extern "C" fn sp_pixel_grid_width( /// /// - `pixel_grid`: instance to read from /// +/// # Panics +/// +/// - when `pixel_grid` is NULL +/// /// # Safety /// /// The caller has to make sure that: @@ -224,12 +260,17 @@ pub unsafe extern "C" fn sp_pixel_grid_width( pub unsafe extern "C" fn sp_pixel_grid_height( pixel_grid: *const SPPixelGrid, ) -> usize { + assert!(!pixel_grid.is_null()); (*pixel_grid).0.height() } /// Gets an unsafe reference to the data of the [SPPixelGrid] instance. /// -/// ## Safety +/// # Panics +/// +/// - when `pixel_grid` is NULL +/// +/// # Safety /// /// The caller has to make sure that: /// @@ -240,6 +281,7 @@ pub unsafe extern "C" fn sp_pixel_grid_height( pub unsafe extern "C" fn sp_pixel_grid_unsafe_data_ref( pixel_grid: *mut SPPixelGrid, ) -> SPByteSlice { + assert!(!pixel_grid.is_null()); let data = (*pixel_grid).0.data_ref_mut(); SPByteSlice { start: data.as_mut_ptr_range().start, From 8d3ca4dfad5002fbd00d00c0948d4ae0b058ca84 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Mon, 14 Oct 2024 22:07:13 +0200 Subject: [PATCH 12/27] clippy fixes --- crates/servicepoint/src/cp437.rs | 2 +- crates/servicepoint/src/primitive_grid.rs | 2 +- crates/servicepoint_binding_c/src/command.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/servicepoint/src/cp437.rs b/crates/servicepoint/src/cp437.rs index 1a4b25d..c6df59c 100644 --- a/crates/servicepoint/src/cp437.rs +++ b/crates/servicepoint/src/cp437.rs @@ -120,7 +120,7 @@ mod feature_cp437 { /* FX */ '≡', '±', '≥', '≤', '⌠', '⌡', '÷', '≈', '°', '∙', '·', '√', 'ⁿ', '²', '■', ' ', ]; - const UTF8_TO_CP437: once_cell::sync::Lazy> = + static UTF8_TO_CP437: once_cell::sync::Lazy> = once_cell::sync::Lazy::new(|| { let pairs = CP437_TO_UTF8 .iter() diff --git a/crates/servicepoint/src/primitive_grid.rs b/crates/servicepoint/src/primitive_grid.rs index 0b947b6..ca2ce05 100644 --- a/crates/servicepoint/src/primitive_grid.rs +++ b/crates/servicepoint/src/primitive_grid.rs @@ -118,7 +118,7 @@ impl PrimitiveGrid { F: FnMut(&T) -> TConverted, { let data = self.data_ref().iter().map(f).collect::>(); - PrimitiveGrid::load(self.width(), self.height(), &*data) + PrimitiveGrid::load(self.width(), self.height(), &data) } } diff --git a/crates/servicepoint_binding_c/src/command.rs b/crates/servicepoint_binding_c/src/command.rs index d273437..4bbc408 100644 --- a/crates/servicepoint_binding_c/src/command.rs +++ b/crates/servicepoint_binding_c/src/command.rs @@ -4,7 +4,7 @@ use std::ptr::null_mut; -use servicepoint::{Brightness, Command, Origin}; +use servicepoint::{Brightness, Origin}; use crate::{ SPBitVec, SPBrightnessGrid, SPCompressionCode, SPCp437Grid, SPPacket, From f64ce6e57e3b93260eb5774d323cdd29fc684206 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Mon, 14 Oct 2024 22:08:01 +0200 Subject: [PATCH 13/27] regenerate language bindings --- .../examples/lang_c/include/servicepoint.h | 584 ++++++++++++------ .../ServicePoint/BindGen/ServicePoint.g.cs | 562 +++++++++++------ 2 files changed, 767 insertions(+), 379 deletions(-) diff --git a/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h b/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h index 453c6b1..2f9cab7 100644 --- a/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h +++ b/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h @@ -107,7 +107,7 @@ typedef struct SPBrightnessGrid SPBrightnessGrid; * * This struct and associated functions implement the UDP protocol for the display. * - * To send a `SPCommand`, use a `SPConnection`. + * To send a [SPCommand], use a [SPConnection]. * * # Examples * @@ -197,13 +197,19 @@ extern "C" { #endif // __cplusplus /** - * Clones a `SPBitVec`. + * Clones a [SPBitVec]. + * + * returns: new [SPBitVec] instance. Will never return NULL. + * + * # Panics + * + * - when `bit_vec` is NULL * * # Safety * * The caller has to make sure that: * - * - `bit_vec` points to a valid `SPBitVec` + * - `bit_vec` points to a valid [SPBitVec] * - `bit_vec` is not written to concurrently * - the returned instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_bit_vec_free`. @@ -211,37 +217,45 @@ extern "C" { struct SPBitVec *sp_bit_vec_clone(const struct SPBitVec *bit_vec); /** - * Sets the value of all bits in the `SPBitVec`. + * Sets the value of all bits in the [SPBitVec]. * * # Arguments * * - `bit_vec`: instance to write to * - `value`: the value to set all bits to * + * # Panics + * + * - when `bit_vec` is NULL + * * # Safety * * The caller has to make sure that: * - * - `bit_vec` points to a valid `SPBitVec` + * - `bit_vec` points to a valid [SPBitVec] * - `bit_vec` is not written to or read from concurrently */ void sp_bit_vec_fill(struct SPBitVec *bit_vec, bool value); /** - * Deallocates a `SPBitVec`. + * Deallocates a [SPBitVec]. + * + * # Panics + * + * - when `but_vec` is NULL * * # Safety * * The caller has to make sure that: * - * - `bit_vec` points to a valid `SPBitVec` + * - `bit_vec` points to a valid [SPBitVec] * - `bit_vec` is not used concurrently or after this call - * - `bit_vec` was not passed to another consuming function, e.g. to create a `SPCommand` + * - `bit_vec` was not passed to another consuming function, e.g. to create a [SPCommand] */ void sp_bit_vec_free(struct SPBitVec *bit_vec); /** - * Gets the value of a bit from the `SPBitVec`. + * Gets the value of a bit from the [SPBitVec]. * * # Arguments * @@ -252,13 +266,14 @@ void sp_bit_vec_free(struct SPBitVec *bit_vec); * * # Panics * - * When accessing `index` out of bounds. + * - when `bit_vec` is NULL + * - when accessing `index` out of bounds * * # Safety * * The caller has to make sure that: * - * - `bit_vec` points to a valid `SPBitVec` + * - `bit_vec` points to a valid [SPBitVec] * - `bit_vec` is not written to concurrently */ bool sp_bit_vec_get(const struct SPBitVec *bit_vec, size_t index); @@ -270,31 +285,45 @@ bool sp_bit_vec_get(const struct SPBitVec *bit_vec, size_t index); * * - `bit_vec`: instance to write to * + * # Panics + * + * - when `bit_vec` is NULL + * * # Safety * * The caller has to make sure that: * - * - `bit_vec` points to a valid `SPBitVec` + * - `bit_vec` points to a valid [SPBitVec] */ bool sp_bit_vec_is_empty(const struct SPBitVec *bit_vec); /** - * Gets the length of the `SPBitVec` in bits. + * Gets the length of the [SPBitVec] in bits. * * # Arguments * * - `bit_vec`: instance to write to * + * # Panics + * + * - when `bit_vec` is NULL + * * # Safety * * The caller has to make sure that: * - * - `bit_vec` points to a valid `SPBitVec` + * - `bit_vec` points to a valid [SPBitVec] */ size_t sp_bit_vec_len(const struct SPBitVec *bit_vec); /** - * 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. + * + * returns: [SPBitVec] instance containing data. Will never return NULL. + * + * # Panics + * + * - when `data` is NULL * * # Safety * @@ -309,17 +338,17 @@ struct SPBitVec *sp_bit_vec_load(const uint8_t *data, size_t data_length); /** - * Creates a new `SPBitVec` instance. + * Creates a new [SPBitVec] instance. * * # Arguments * * - `size`: size in bits. * - * returns: `SPBitVec` with all bits set to false. Will never return NULL. + * returns: [SPBitVec] with all bits set to false. Will never return NULL. * * # Panics * - * When `size` is not divisible by 8. + * - when `size` is not divisible by 8. * * # Safety * @@ -331,7 +360,7 @@ struct SPBitVec *sp_bit_vec_load(const uint8_t *data, struct SPBitVec *sp_bit_vec_new(size_t size); /** - * Sets the value of a bit in the `SPBitVec`. + * Sets the value of a bit in the [SPBitVec]. * * # Arguments * @@ -339,50 +368,59 @@ struct SPBitVec *sp_bit_vec_new(size_t size); * - `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. + * - when `bit_vec` is NULL + * - when accessing `index` out of bounds * * # Safety * * The caller has to make sure that: * - * - `bit_vec` points to a valid `SPBitVec` + * - `bit_vec` points to a valid [SPBitVec] * - `bit_vec` is not written to or read from concurrently */ void sp_bit_vec_set(struct SPBitVec *bit_vec, size_t index, bool value); /** - * Gets an unsafe reference to the data of the `SPBitVec` instance. + * Gets an unsafe reference to the data of the [SPBitVec] instance. * * # Arguments * * - `bit_vec`: instance to write to * + * # Panics + * + * - when `bit_vec` is NULL + * * ## Safety * * The caller has to make sure that: * - * - `bit_vec` points to a valid `SPBitVec` - * - the returned memory range is never accessed after the passed `SPBitVec` has been freed - * - the returned memory range is never accessed concurrently, either via the `SPBitVec` or directly + * - `bit_vec` points to a valid [SPBitVec] + * - the returned memory range is never accessed after the passed [SPBitVec] has been freed + * - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly */ struct SPByteSlice sp_bit_vec_unsafe_data_ref(struct SPBitVec *bit_vec); /** - * 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`. @@ -390,7 +428,7 @@ struct SPByteSlice sp_bit_vec_unsafe_data_ref(struct SPBitVec *bit_vec); struct SPBrightnessGrid *sp_brightness_grid_clone(const struct SPBrightnessGrid *brightness_grid); /** - * Sets the value of all cells in the `SPBrightnessGrid`. + * Sets the value of all cells in the [SPBrightnessGrid]. * * # Arguments * @@ -399,32 +437,37 @@ struct SPBrightnessGrid *sp_brightness_grid_clone(const struct SPBrightnessGrid * * # 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 */ void sp_brightness_grid_fill(struct SPBrightnessGrid *brightness_grid, uint8_t value); /** - * 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` + * - `brightness_grid` was not passed to another consuming function, e.g. to create a [SPCommand] */ void sp_brightness_grid_free(struct SPBrightnessGrid *brightness_grid); @@ -436,15 +479,18 @@ void sp_brightness_grid_free(struct SPBrightnessGrid *brightness_grid); * - `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 */ uint8_t sp_brightness_grid_get(const struct SPBrightnessGrid *brightness_grid, @@ -452,26 +498,35 @@ uint8_t sp_brightness_grid_get(const struct SPBrightnessGrid *brightness_grid, size_t y); /** - * 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] */ size_t sp_brightness_grid_height(const struct SPBrightnessGrid *brightness_grid); /** - * 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 * @@ -488,9 +543,9 @@ struct SPBrightnessGrid *sp_brightness_grid_load(size_t width, size_t data_length); /** - * 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 * @@ -503,7 +558,7 @@ struct SPBrightnessGrid *sp_brightness_grid_new(size_t width, size_t height); /** - * Sets the value of the specified position in the `SPBrightnessGrid`. + * Sets the value of the specified position in the [SPBrightnessGrid]. * * # Arguments * @@ -515,6 +570,7 @@ struct SPBrightnessGrid *sp_brightness_grid_new(size_t width, * * # Panics * + * - when `brightness_grid` is NULL * - When accessing `x` or `y` out of bounds. * - When providing an invalid brightness value * @@ -522,7 +578,7 @@ struct SPBrightnessGrid *sp_brightness_grid_new(size_t width, * * The caller has to make sure that: * - * - `brightness_grid` points to a valid `SPBitVec` + * - `brightness_grid` points to a valid [SPBitVec] * - `brightness_grid` is not written to or read from concurrently */ void sp_brightness_grid_set(struct SPBrightnessGrid *brightness_grid, @@ -531,34 +587,46 @@ void sp_brightness_grid_set(struct SPBrightnessGrid *brightness_grid, uint8_t value); /** - * 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`. * - * The caller has to make sure that: + * # Panics * - * - `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 - */ -struct SPByteSlice sp_brightness_grid_unsafe_data_ref(struct SPBrightnessGrid *brightness_grid); - -/** - * Gets the width of the `SPBrightnessGrid` instance. - * - * # Arguments - * - * - `brightness_grid`: instance to read from + * - 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] + * - 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 + */ +struct SPByteSlice sp_brightness_grid_unsafe_data_ref(struct SPBrightnessGrid *brightness_grid); + +/** + * 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] */ size_t sp_brightness_grid_width(const struct SPBrightnessGrid *brightness_grid); @@ -568,20 +636,25 @@ size_t sp_brightness_grid_width(const struct SPBrightnessGrid *brightness_grid); * The screen will continuously overwrite more pixel data without regarding the offset, meaning * once the starting row is full, overwriting will continue on column 0. * - * The contained `SPBitVec` is always uncompressed. + * The contained [SPBitVec] is always uncompressed. * - * The passed `SPBitVec` gets consumed. + * The passed [SPBitVec] gets consumed. * - * Returns: a new `Command::BitmapLinear` instance. Will never return NULL. + * Returns: a new [Command::BitmapLinear] instance. Will never return NULL. + * + * # Panics + * + * - when `bit_vec` is null + * - when `compression_code` is not a valid value * * # Safety * * The caller has to make sure that: * - * - `bit_vec` points to a valid instance of `SPBitVec` + * - `bit_vec` points to a valid instance of [SPBitVec] * - `bit_vec` is not used concurrently or after this call * - `compression` matches one of the allowed enum values - * - 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`. */ struct SPCommand *sp_command_bitmap_linear(size_t offset, @@ -594,20 +667,25 @@ struct SPCommand *sp_command_bitmap_linear(size_t offset, * The screen will continuously overwrite more pixel data without regarding the offset, meaning * once the starting row is full, overwriting will continue on column 0. * - * The contained `SPBitVec` is always uncompressed. + * The contained [SPBitVec] is always uncompressed. * - * The passed `SPBitVec` gets consumed. + * The passed [SPBitVec] gets consumed. * - * Returns: a new `Command::BitmapLinearAnd` instance. Will never return NULL. + * Returns: a new [Command::BitmapLinearAnd] instance. Will never return NULL. + * + * # Panics + * + * - when `bit_vec` is null + * - when `compression_code` is not a valid value * * # Safety * * The caller has to make sure that: * - * - `bit_vec` points to a valid instance of `SPBitVec` + * - `bit_vec` points to a valid instance of [SPBitVec] * - `bit_vec` is not used concurrently or after this call * - `compression` matches one of the allowed enum values - * - 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`. */ struct SPCommand *sp_command_bitmap_linear_and(size_t offset, @@ -620,20 +698,25 @@ struct SPCommand *sp_command_bitmap_linear_and(size_t offset, * The screen will continuously overwrite more pixel data without regarding the offset, meaning * once the starting row is full, overwriting will continue on column 0. * - * The contained `SPBitVec` is always uncompressed. + * The contained [SPBitVec] is always uncompressed. * - * The passed `SPBitVec` gets consumed. + * The passed [SPBitVec] gets consumed. * - * Returns: a new `Command::BitmapLinearOr` instance. Will never return NULL. + * Returns: a new [Command::BitmapLinearOr] instance. Will never return NULL. + * + * # Panics + * + * - when `bit_vec` is null + * - when `compression_code` is not a valid value * * # Safety * * The caller has to make sure that: * - * - `bit_vec` points to a valid instance of `SPBitVec` + * - `bit_vec` points to a valid instance of [SPBitVec] * - `bit_vec` is not used concurrently or after this call * - `compression` matches one of the allowed enum values - * - 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`. */ struct SPCommand *sp_command_bitmap_linear_or(size_t offset, @@ -643,18 +726,23 @@ struct SPCommand *sp_command_bitmap_linear_or(size_t offset, /** * Sets a window of pixels to the specified values. * - * The passed `SPPixelGrid` gets consumed. + * The passed [SPPixelGrid] gets consumed. * - * Returns: a new `Command::BitmapLinearWin` instance. Will never return NULL. + * Returns: a new [Command::BitmapLinearWin] instance. Will never return NULL. + * + * # Panics + * + * - when `pixel_grid` is null + * - when `compression_code` is not a valid value * * # Safety * * The caller has to make sure that: * - * - `pixel_grid` points to a valid instance of `SPPixelGrid` + * - `pixel_grid` points to a valid instance of [SPPixelGrid] * - `pixel_grid` is not used concurrently or after this call * - `compression` matches one of the allowed enum values - * - 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`. */ struct SPCommand *sp_command_bitmap_linear_win(size_t x, @@ -668,20 +756,25 @@ struct SPCommand *sp_command_bitmap_linear_win(size_t x, * The screen will continuously overwrite more pixel data without regarding the offset, meaning * once the starting row is full, overwriting will continue on column 0. * - * The contained `SPBitVec` is always uncompressed. + * The contained [SPBitVec] is always uncompressed. * - * The passed `SPBitVec` gets consumed. + * The passed [SPBitVec] gets consumed. * - * Returns: a new `Command::BitmapLinearXor` instance. Will never return NULL. + * Returns: a new [Command::BitmapLinearXor] instance. Will never return NULL. + * + * # Panics + * + * - when `bit_vec` is null + * - when `compression_code` is not a valid value * * # Safety * * The caller has to make sure that: * - * - `bit_vec` points to a valid instance of `SPBitVec` + * - `bit_vec` points to a valid instance of [SPBitVec] * - `bit_vec` is not used concurrently or after this call * - `compression` matches one of the allowed enum values - * - 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`. */ struct SPCommand *sp_command_bitmap_linear_xor(size_t offset, @@ -691,7 +784,7 @@ struct SPCommand *sp_command_bitmap_linear_xor(size_t offset, /** * Set the brightness of all tiles to the same value. * - * Returns: a new `Command::Brightness` instance. Will never return NULL. + * Returns: a new [Command::Brightness] instance. Will never return NULL. * * # Panics * @@ -701,7 +794,7 @@ struct SPCommand *sp_command_bitmap_linear_xor(size_t offset, * * The caller has to make sure that: * - * - 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`. */ struct SPCommand *sp_command_brightness(uint8_t brightness); @@ -709,17 +802,21 @@ struct SPCommand *sp_command_brightness(uint8_t 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. + * Returns: a new [Command::CharBrightness] instance. Will never return NULL. + * + * # Panics + * + * - when `grid` is NULL * * # Safety * * 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 + * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_command_free`. */ struct SPCommand *sp_command_char_brightness(size_t x, @@ -731,7 +828,7 @@ struct SPCommand *sp_command_char_brightness(size_t x, * * Does not affect brightness. * - * Returns: a new `Command::Clear` instance. Will never return NULL. + * Returns: a new [Command::Clear] instance. Will never return NULL. * * # Examples * @@ -743,21 +840,27 @@ struct SPCommand *sp_command_char_brightness(size_t x, * * The caller has to make sure that: * - * - 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`. */ struct SPCommand *sp_command_clear(void); /** - * Clones a `SPCommand` instance. + * Clones a [SPCommand] instance. + * + * returns: new [SPCommand] instance. Will never return NULL. + * + * # Panics + * + * - when `command` is NULL * * # Safety * * The caller has to make sure that: * - * - `command` points to a valid instance of `SPCommand` + * - `command` points to a valid instance of [SPCommand] * - `command` is not written to concurrently - * - 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`. */ struct SPCommand *sp_command_clone(const struct SPCommand *command); @@ -765,22 +868,21 @@ struct SPCommand *sp_command_clone(const struct SPCommand *command); /** * Show text on the screen. * - *
- * The library does not currently convert between UTF-8 and CP-437. - * Because Rust expects UTF-8 strings, it might be necessary to only send ASCII for now. - *
+ * The passed [SPCp437Grid] gets consumed. * - * The passed `SPCp437Grid` gets consumed./// + * Returns: a new [Command::Cp437Data] instance. Will never return NULL. * - * Returns: a new `Command::Cp437Data` instance. Will never return NULL. + * # Panics + * + * - when `grid` is null * * # Safety * * The caller has to make sure that: * - * - `grid` points to a valid instance of `SPCp437Grid` + * - `grid` points to a valid instance of [SPCp437Grid] * - `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`. */ struct SPCommand *sp_command_cp437_data(size_t x, @@ -796,13 +898,13 @@ struct SPCommand *sp_command_cp437_data(size_t x, * * The caller has to make sure that: * - * - 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`. */ struct SPCommand *sp_command_fade_out(void); /** - * Deallocates a `SPCommand`. + * Deallocates a [SPCommand]. * * # Examples * @@ -811,13 +913,17 @@ struct SPCommand *sp_command_fade_out(void); * sp_command_free(c); * ``` * + * # Panics + * + * - when `command` is NULL + * * # Safety * * The caller has to make sure that: * - * - `command` points to a valid `SPCommand` + * - `command` points to a valid [SPCommand] * - `command` is not used concurrently or after this call - * - `command` was not passed to another consuming function, e.g. to create a `SPPacket` + * - `command` was not passed to another consuming function, e.g. to create a [SPPacket] */ void sp_command_free(struct SPCommand *command); @@ -826,56 +932,64 @@ void sp_command_free(struct SPCommand *command); * * Please do not send this in your normal program flow. * - * Returns: a new `Command::HardReset` instance. Will never return NULL. + * Returns: a new [Command::HardReset] instance. Will never return NULL. * * # Safety * * The caller has to make sure that: * - * - 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`. */ struct SPCommand *sp_command_hard_reset(void); /** - * Tries to turn a `SPPacket` into a `SPCommand`. + * Tries to turn a [SPPacket] into a [SPCommand]. * * The packet is deallocated in the process. * - * Returns: pointer to new `SPCommand` instance or NULL + * Returns: pointer to new [SPCommand] instance or NULL if parsing failed. + * + * # Panics + * + * - when `packet` is NULL * * # Safety * * The caller has to make sure that: * - * - `SPPacket` points to a valid instance of `SPPacket` - * - `SPPacket` is not used concurrently or after this call + * - [SPPacket] points to a valid instance of [SPPacket] + * - [SPPacket] is not used concurrently or after this call * - the result is checked for NULL - * - 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`. */ struct SPCommand *sp_command_try_from_packet(struct SPPacket *packet); /** - * Closes and deallocates a `SPConnection`. + * Closes and deallocates a [SPConnection]. + * + * # Panics + * + * - when `connection` is NULL * * # Safety * * The caller has to make sure that: * - * - `connection` points to a valid `SPConnection` + * - `connection` points to a valid [SPConnection] * - `connection` is not used concurrently or after this call */ void sp_connection_free(struct SPConnection *connection); /** - * Creates a new instance of `SPConnection`. + * Creates a new instance of [SPConnection]. * * returns: NULL if connection fails, or connected instance * * # Panics * - * Bad string encoding + * - when `host` is null or an invalid host * * # Safety * @@ -887,51 +1001,65 @@ void sp_connection_free(struct SPConnection *connection); struct SPConnection *sp_connection_open(const char *host); /** - * Sends a `SPCommand` to the display using the `SPConnection`. + * Sends a [SPCommand] to the display using the [SPConnection]. * * The passed `command` gets consumed. * * returns: true in case of success * + * # Panics + * + * - when `connection` is NULL + * - when `command` is NULL + * * # Safety * * The caller has to make sure that: * - * - `connection` points to a valid instance of `SPConnection` - * - `command` points to a valid instance of `SPPacket` + * - `connection` points to a valid instance of [SPConnection] + * - `command` points to a valid instance of [SPPacket] * - `command` is not used concurrently or after this call */ bool sp_connection_send_command(const struct SPConnection *connection, struct SPCommand *command); /** - * Sends a `SPPacket` to the display using the `SPConnection`. + * Sends a [SPPacket] to the display using the [SPConnection]. * * The passed `packet` gets consumed. * * returns: true in case of success * + * # Panics + * + * - when `connection` is NULL + * - when `packet` is NULL + * * # Safety * * The caller has to make sure that: * - * - `connection` points to a valid instance of `SPConnection` - * - `packet` points to a valid instance of `SPPacket` + * - `connection` points to a valid instance of [SPConnection] + * - `packet` points to a valid instance of [SPPacket] * - `packet` is not used concurrently or after this call */ bool sp_connection_send_packet(const struct SPConnection *connection, struct SPPacket *packet); /** - * Clones a `SPCp437Grid`. + * Clones a [SPCp437Grid]. * * Will never return NULL. * + * # Panics + * + * - when `cp437_grid` is NULL + * * # Safety * * The caller has to make sure that: * - * - `cp437_grid` points to a valid `SPCp437Grid` + * - `cp437_grid` points to a valid [SPCp437Grid] * - `cp437_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_cp437_grid_free`. @@ -939,32 +1067,40 @@ bool sp_connection_send_packet(const struct SPConnection *connection, struct SPCp437Grid *sp_cp437_grid_clone(const struct SPCp437Grid *cp437_grid); /** - * Sets the value of all cells in the `SPCp437Grid`. + * Sets the value of all cells in the [SPCp437Grid]. * * # Arguments * * - `cp437_grid`: instance to write to * - `value`: the value to set all cells to * + * # Panics + * + * - when `cp437_grid` is NULL + * * # Safety * * The caller has to make sure that: * - * - `cp437_grid` points to a valid `SPCp437Grid` + * - `cp437_grid` points to a valid [SPCp437Grid] * - `cp437_grid` is not written to or read from concurrently */ void sp_cp437_grid_fill(struct SPCp437Grid *cp437_grid, uint8_t value); /** - * Deallocates a `SPCp437Grid`. + * Deallocates a [SPCp437Grid]. + * + * # Panics + * + * - when `cp437_grid` is NULL * * # Safety * * The caller has to make sure that: * - * - `cp437_grid` points to a valid `SPCp437Grid` + * - `cp437_grid` points to a valid [SPCp437Grid] * - `cp437_grid` is not used concurrently or after cp437_grid call - * - `cp437_grid` was not passed to another consuming function, e.g. to create a `SPCommand` + * - `cp437_grid` was not passed to another consuming function, e.g. to create a [SPCommand] */ void sp_cp437_grid_free(struct SPCp437Grid *cp437_grid); @@ -978,13 +1114,14 @@ void sp_cp437_grid_free(struct SPCp437Grid *cp437_grid); * * # Panics * - * When accessing `x` or `y` out of bounds. + * - when `cp437_grid` is NULL + * - when accessing `x` or `y` out of bounds * * # Safety * * The caller has to make sure that: * - * - `cp437_grid` points to a valid `SPCp437Grid` + * - `cp437_grid` points to a valid [SPCp437Grid] * - `cp437_grid` is not written to concurrently */ uint8_t sp_cp437_grid_get(const struct SPCp437Grid *cp437_grid, @@ -992,28 +1129,33 @@ uint8_t sp_cp437_grid_get(const struct SPCp437Grid *cp437_grid, size_t y); /** - * Gets the height of the `SPCp437Grid` instance. + * Gets the height of the [SPCp437Grid] instance. * * # Arguments * * - `cp437_grid`: instance to read from * + * # Panics + * + * - when `cp437_grid` is NULL + * * # Safety * * The caller has to make sure that: * - * - `cp437_grid` points to a valid `SPCp437Grid` + * - `cp437_grid` points to a valid [SPCp437Grid] */ size_t sp_cp437_grid_height(const struct SPCp437Grid *cp437_grid); /** - * Loads a `SPCp437Grid` with the specified dimensions from the provided data. + * Loads a [SPCp437Grid] with the specified dimensions from the provided data. * * 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 * @@ -1030,9 +1172,9 @@ struct SPCp437Grid *sp_cp437_grid_load(size_t width, size_t data_length); /** - * Creates a new `SPCp437Grid` with the specified dimensions. + * Creates a new [SPCp437Grid] with the specified dimensions. * - * returns: `SPCp437Grid` initialized to 0. + * returns: [SPCp437Grid] initialized to 0. Will never return NULL. * * # Safety * @@ -1045,7 +1187,7 @@ struct SPCp437Grid *sp_cp437_grid_new(size_t width, size_t height); /** - * Sets the value of the specified position in the `SPCp437Grid`. + * Sets the value of the specified position in the [SPCp437Grid]. * * # Arguments * @@ -1057,13 +1199,14 @@ struct SPCp437Grid *sp_cp437_grid_new(size_t width, * * # Panics * - * When accessing `x` or `y` out of bounds. + * - when `cp437_grid` is NULL + * - when accessing `x` or `y` out of bounds * * # Safety * * The caller has to make sure that: * - * - `cp437_grid` points to a valid `SPBitVec` + * - `cp437_grid` points to a valid [SPBitVec] * - `cp437_grid` is not written to or read from concurrently */ void sp_cp437_grid_set(struct SPCp437Grid *cp437_grid, @@ -1072,45 +1215,57 @@ void sp_cp437_grid_set(struct SPCp437Grid *cp437_grid, uint8_t value); /** - * Gets an unsafe reference to the data of the `SPCp437Grid` instance. + * Gets an unsafe reference to the data of the [SPCp437Grid] instance. * * Will never return NULL. * + * # Panics + * + * - when `cp437_grid` is NULL + * * ## Safety * * The caller has to make sure that: * - * - `cp437_grid` points to a valid `SPCp437Grid` - * - the returned memory range is never accessed after the passed `SPCp437Grid` has been freed - * - the returned memory range is never accessed concurrently, either via the `SPCp437Grid` or directly + * - `cp437_grid` points to a valid [SPCp437Grid] + * - the returned memory range is never accessed after the passed [SPCp437Grid] has been freed + * - the returned memory range is never accessed concurrently, either via the [SPCp437Grid] or directly */ struct SPByteSlice sp_cp437_grid_unsafe_data_ref(struct SPCp437Grid *cp437_grid); /** - * Gets the width of the `SPCp437Grid` instance. + * Gets the width of the [SPCp437Grid] instance. * * # Arguments * * - `cp437_grid`: instance to read from * + * # Panics + * + * - when `cp437_grid` is NULL + * * # Safety * * The caller has to make sure that: * - * - `cp437_grid` points to a valid `SPCp437Grid` + * - `cp437_grid` points to a valid [SPCp437Grid] */ size_t sp_cp437_grid_width(const struct SPCp437Grid *cp437_grid); /** - * Clones a `SPPacket`. + * Clones a [SPPacket]. * * Will never return NULL. * + * # Panics + * + * - when `packet` is NULL + * * # Safety * * The caller has to make sure that: * - * - `packet` points to a valid `SPPacket` + * - `packet` points to a valid [SPPacket] * - `packet` is not written to concurrently * - the returned instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_packet_free`. @@ -1118,61 +1273,77 @@ size_t sp_cp437_grid_width(const struct SPCp437Grid *cp437_grid); struct SPPacket *sp_packet_clone(const struct SPPacket *packet); /** - * Deallocates a `SPPacket`. + * Deallocates a [SPPacket]. + * + * # Panics + * + * - when `sp_packet_free` is NULL * * # Safety * * The caller has to make sure that: * - * - `packet` points to a valid `SPPacket` + * - `packet` points to a valid [SPPacket] * - `packet` is not used concurrently or after this call */ void sp_packet_free(struct SPPacket *packet); /** - * Turns a `SPCommand` into a `SPPacket`. - * The `SPCommand` gets consumed. + * Turns a [SPCommand] into a [SPPacket]. + * The [SPCommand] gets consumed. * * Will never return NULL. * + * # Panics + * + * - when `command` is NULL + * * # Safety * * The caller has to make sure that: * - * - `SPCommand` points to a valid instance of `SPCommand` - * - `SPCommand` is not used concurrently or after this call - * - the returned `SPPacket` instance is freed in some way, either by using a consuming function or + * - [SPCommand] points to a valid instance of [SPCommand] + * - [SPCommand] is not used concurrently or after this call + * - the returned [SPPacket] instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_packet_free`. */ struct SPPacket *sp_packet_from_command(struct SPCommand *command); /** - * 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. * * returns: NULL in case of an error, pointer to the allocated packet otherwise * + * # Panics + * + * - when `data` is NULL + * * # Safety * * The caller has to make sure that: * * - `data` points to a valid memory region of at least `length` bytes * - `data` is not written to concurrently - * - the returned `SPPacket` instance is freed in some way, either by using a consuming function or + * - the returned [SPPacket] instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_packet_free`. */ struct SPPacket *sp_packet_try_load(const uint8_t *data, size_t length); /** - * Clones a `SPPixelGrid`. + * Clones a [SPPixelGrid]. * * Will never return NULL. * + * # Panics + * + * - when `pixel_grid` is NULL + * * # Safety * * The caller has to make sure that: * - * - `pixel_grid` points to a valid `SPPixelGrid` + * - `pixel_grid` points to a valid [SPPixelGrid] * - `pixel_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_pixel_grid_free`. @@ -1180,37 +1351,45 @@ struct SPPacket *sp_packet_try_load(const uint8_t *data, struct SPPixelGrid *sp_pixel_grid_clone(const struct SPPixelGrid *pixel_grid); /** - * Sets the state of all pixels in the `SPPixelGrid`. + * Sets the state of all pixels in the [SPPixelGrid]. * * # Arguments * * - `pixel_grid`: instance to write to * - `value`: the value to set all pixels to * + * # Panics + * + * - when `pixel_grid` is NULL + * * # Safety * * The caller has to make sure that: * - * - `pixel_grid` points to a valid `SPPixelGrid` + * - `pixel_grid` points to a valid [SPPixelGrid] * - `pixel_grid` is not written to or read from concurrently */ void sp_pixel_grid_fill(struct SPPixelGrid *pixel_grid, bool value); /** - * Deallocates a `SPPixelGrid`. + * Deallocates a [SPPixelGrid]. + * + * # Panics + * + * - when `pixel_grid` is NULL * * # Safety * * The caller has to make sure that: * - * - `pixel_grid` points to a valid `SPPixelGrid` + * - `pixel_grid` points to a valid [SPPixelGrid] * - `pixel_grid` is not used concurrently or after pixel_grid call - * - `pixel_grid` was not passed to another consuming function, e.g. to create a `SPCommand` + * - `pixel_grid` was not passed to another consuming function, e.g. to create a [SPCommand] */ void sp_pixel_grid_free(struct SPPixelGrid *pixel_grid); /** - * Gets the current value at the specified position in the `SPPixelGrid`. + * Gets the current value at the specified position in the [SPPixelGrid]. * * # Arguments * @@ -1219,13 +1398,14 @@ void sp_pixel_grid_free(struct SPPixelGrid *pixel_grid); * * # Panics * - * When accessing `x` or `y` out of bounds. + * - when `pixel_grid` is NULL + * - when accessing `x` or `y` out of bounds * * # Safety * * The caller has to make sure that: * - * - `pixel_grid` points to a valid `SPPixelGrid` + * - `pixel_grid` points to a valid [SPPixelGrid] * - `pixel_grid` is not written to concurrently */ bool sp_pixel_grid_get(const struct SPPixelGrid *pixel_grid, @@ -1233,32 +1413,37 @@ bool sp_pixel_grid_get(const struct SPPixelGrid *pixel_grid, size_t y); /** - * Gets the height in pixels of the `SPPixelGrid` instance. + * Gets the height in pixels of the [SPPixelGrid] instance. * * # Arguments * * - `pixel_grid`: instance to read from * + * # Panics + * + * - when `pixel_grid` is NULL + * * # Safety * * The caller has to make sure that: * - * - `pixel_grid` points to a valid `SPPixelGrid` + * - `pixel_grid` points to a valid [SPPixelGrid] */ size_t sp_pixel_grid_height(const struct SPPixelGrid *pixel_grid); /** - * Loads a `SPPixelGrid` with the specified dimensions from the provided data. + * Loads a [SPPixelGrid] with the specified dimensions from the provided data. * * # Arguments * * - `width`: size in pixels in x-direction * - `height`: size in pixels in y-direction * - * returns: `SPPixelGrid` that contains a copy of the provided data. Will never return NULL. + * returns: [SPPixelGrid] that contains a copy of the provided data. Will never return NULL. * * # Panics * + * - when `data` is NULL * - when the dimensions and data size do not match exactly. * - when the width is not dividable by 8 * @@ -1276,14 +1461,14 @@ struct SPPixelGrid *sp_pixel_grid_load(size_t width, size_t data_length); /** - * Creates a new `SPPixelGrid` with the specified dimensions. + * Creates a new [SPPixelGrid] with the specified dimensions. * * # Arguments * * - `width`: size in pixels in x-direction * - `height`: size in pixels in y-direction * - * returns: `SPPixelGrid` initialized to all pixels off. Will never return NULL. + * returns: [SPPixelGrid] initialized to all pixels off. Will never return NULL. * * # Panics * @@ -1300,7 +1485,7 @@ struct SPPixelGrid *sp_pixel_grid_new(size_t width, size_t height); /** - * Sets the value of the specified position in the `SPPixelGrid`. + * Sets the value of the specified position in the [SPPixelGrid]. * * # Arguments * @@ -1312,13 +1497,14 @@ struct SPPixelGrid *sp_pixel_grid_new(size_t width, * * # Panics * - * When accessing `x` or `y` out of bounds. + * - when `pixel_grid` is NULL + * - when accessing `x` or `y` out of bounds * * # Safety * * The caller has to make sure that: * - * - `pixel_grid` points to a valid `SPPixelGrid` + * - `pixel_grid` points to a valid [SPPixelGrid] * - `pixel_grid` is not written to or read from concurrently */ void sp_pixel_grid_set(struct SPPixelGrid *pixel_grid, @@ -1327,30 +1513,38 @@ void sp_pixel_grid_set(struct SPPixelGrid *pixel_grid, bool value); /** - * Gets an unsafe reference to the data of the `SPPixelGrid` instance. + * Gets an unsafe reference to the data of the [SPPixelGrid] instance. * - * ## Safety + * # Panics * - * The caller has to make sure that: - * - * - `pixel_grid` points to a valid `SPPixelGrid` - * - the returned memory range is never accessed after the passed `SPPixelGrid` has been freed - * - the returned memory range is never accessed concurrently, either via the `SPPixelGrid` or directly - */ -struct SPByteSlice sp_pixel_grid_unsafe_data_ref(struct SPPixelGrid *pixel_grid); - -/** - * Gets the width in pixels of the `SPPixelGrid` instance. - * - * # Arguments - * - * - `pixel_grid`: instance to read from + * - when `pixel_grid` is NULL * * # Safety * * The caller has to make sure that: * - * - `pixel_grid` points to a valid `SPPixelGrid` + * - `pixel_grid` points to a valid [SPPixelGrid] + * - the returned memory range is never accessed after the passed [SPPixelGrid] has been freed + * - the returned memory range is never accessed concurrently, either via the [SPPixelGrid] or directly + */ +struct SPByteSlice sp_pixel_grid_unsafe_data_ref(struct SPPixelGrid *pixel_grid); + +/** + * Gets the width in pixels of the [SPPixelGrid] instance. + * + * # Arguments + * + * - `pixel_grid`: instance to read from + * + * # Panics + * + * - when `pixel_grid` is NULL + * + * # Safety + * + * The caller has to make sure that: + * + * - `pixel_grid` points to a valid [SPPixelGrid] */ size_t sp_pixel_grid_width(const struct SPPixelGrid *pixel_grid); diff --git a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs b/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs index d23b2b9..42a5977 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs @@ -20,17 +20,17 @@ namespace ServicePoint.BindGen /// - /// Creates a new `SPBitVec` instance. + /// Creates a new [SPBitVec] instance. /// /// # Arguments /// /// - `size`: size in bits. /// - /// returns: `SPBitVec` with all bits set to false. Will never return NULL. + /// returns: [SPBitVec] with all bits set to false. Will never return NULL. /// /// # Panics /// - /// When `size` is not divisible by 8. + /// - when `size` is not divisible by 8. /// /// # Safety /// @@ -43,7 +43,13 @@ namespace ServicePoint.BindGen public static extern BitVec* sp_bit_vec_new(nuint size); /// - /// 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. + /// + /// returns: [SPBitVec] instance containing data. Will never return NULL. + /// + /// # Panics + /// + /// - when `data` is NULL /// /// # Safety /// @@ -58,13 +64,19 @@ namespace ServicePoint.BindGen public static extern BitVec* sp_bit_vec_load(byte* data, nuint data_length); /// - /// Clones a `SPBitVec`. + /// Clones a [SPBitVec]. + /// + /// returns: new [SPBitVec] instance. Will never return NULL. + /// + /// # Panics + /// + /// - when `bit_vec` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `bit_vec` points to a valid `SPBitVec` + /// - `bit_vec` points to a valid [SPBitVec] /// - `bit_vec` is not written to concurrently /// - the returned instance is freed in some way, either by using a consuming function or /// by explicitly calling `sp_bit_vec_free`. @@ -73,21 +85,25 @@ namespace ServicePoint.BindGen public static extern BitVec* sp_bit_vec_clone(BitVec* bit_vec); /// - /// Deallocates a `SPBitVec`. + /// Deallocates a [SPBitVec]. + /// + /// # Panics + /// + /// - when `but_vec` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `bit_vec` points to a valid `SPBitVec` + /// - `bit_vec` points to a valid [SPBitVec] /// - `bit_vec` is not used concurrently or after this call - /// - `bit_vec` was not passed to another consuming function, e.g. to create a `SPCommand` + /// - `bit_vec` was not passed to another consuming function, e.g. to create a [SPCommand] /// [DllImport(__DllName, EntryPoint = "sp_bit_vec_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern void sp_bit_vec_free(BitVec* bit_vec); /// - /// Gets the value of a bit from the `SPBitVec`. + /// Gets the value of a bit from the [SPBitVec]. /// /// # Arguments /// @@ -98,13 +114,14 @@ namespace ServicePoint.BindGen /// /// # Panics /// - /// When accessing `index` out of bounds. + /// - when `bit_vec` is NULL + /// - when accessing `index` out of bounds /// /// # Safety /// /// The caller has to make sure that: /// - /// - `bit_vec` points to a valid `SPBitVec` + /// - `bit_vec` points to a valid [SPBitVec] /// - `bit_vec` is not written to concurrently /// [DllImport(__DllName, EntryPoint = "sp_bit_vec_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] @@ -112,7 +129,7 @@ namespace ServicePoint.BindGen public static extern bool sp_bit_vec_get(BitVec* bit_vec, nuint index); /// - /// Sets the value of a bit in the `SPBitVec`. + /// Sets the value of a bit in the [SPBitVec]. /// /// # Arguments /// @@ -120,52 +137,59 @@ namespace ServicePoint.BindGen /// - `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. + /// - when `bit_vec` is NULL + /// - when accessing `index` out of bounds /// /// # Safety /// /// The caller has to make sure that: /// - /// - `bit_vec` points to a valid `SPBitVec` + /// - `bit_vec` points to a valid [SPBitVec] /// - `bit_vec` is not written to or read from concurrently /// [DllImport(__DllName, EntryPoint = "sp_bit_vec_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern void sp_bit_vec_set(BitVec* bit_vec, nuint index, [MarshalAs(UnmanagedType.U1)] bool value); /// - /// Sets the value of all bits in the `SPBitVec`. + /// Sets the value of all bits in the [SPBitVec]. /// /// # Arguments /// /// - `bit_vec`: instance to write to /// - `value`: the value to set all bits to /// + /// # Panics + /// + /// - when `bit_vec` is NULL + /// /// # Safety /// /// The caller has to make sure that: /// - /// - `bit_vec` points to a valid `SPBitVec` + /// - `bit_vec` points to a valid [SPBitVec] /// - `bit_vec` is not written to or read from concurrently /// [DllImport(__DllName, EntryPoint = "sp_bit_vec_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern void sp_bit_vec_fill(BitVec* bit_vec, [MarshalAs(UnmanagedType.U1)] bool value); /// - /// Gets the length of the `SPBitVec` in bits. + /// Gets the length of the [SPBitVec] in bits. /// /// # Arguments /// /// - `bit_vec`: instance to write to /// + /// # Panics + /// + /// - when `bit_vec` is NULL + /// /// # Safety /// /// The caller has to make sure that: /// - /// - `bit_vec` points to a valid `SPBitVec` + /// - `bit_vec` points to a valid [SPBitVec] /// [DllImport(__DllName, EntryPoint = "sp_bit_vec_len", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern nuint sp_bit_vec_len(BitVec* bit_vec); @@ -177,38 +201,46 @@ namespace ServicePoint.BindGen /// /// - `bit_vec`: instance to write to /// + /// # Panics + /// + /// - when `bit_vec` is NULL + /// /// # Safety /// /// The caller has to make sure that: /// - /// - `bit_vec` points to a valid `SPBitVec` + /// - `bit_vec` points to a valid [SPBitVec] /// [DllImport(__DllName, EntryPoint = "sp_bit_vec_is_empty", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool sp_bit_vec_is_empty(BitVec* bit_vec); /// - /// Gets an unsafe reference to the data of the `SPBitVec` instance. + /// Gets an unsafe reference to the data of the [SPBitVec] instance. /// /// # Arguments /// /// - `bit_vec`: instance to write to /// + /// # Panics + /// + /// - when `bit_vec` is NULL + /// /// ## Safety /// /// The caller has to make sure that: /// - /// - `bit_vec` points to a valid `SPBitVec` - /// - the returned memory range is never accessed after the passed `SPBitVec` has been freed - /// - the returned memory range is never accessed concurrently, either via the `SPBitVec` or directly + /// - `bit_vec` points to a valid [SPBitVec] + /// - the returned memory range is never accessed after the passed [SPBitVec] has been freed + /// - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly /// [DllImport(__DllName, EntryPoint = "sp_bit_vec_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern ByteSlice sp_bit_vec_unsafe_data_ref(BitVec* bit_vec); /// - /// 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 /// @@ -221,11 +253,14 @@ namespace ServicePoint.BindGen public static extern BrightnessGrid* sp_brightness_grid_new(nuint width, nuint height); /// - /// 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 /// @@ -240,17 +275,23 @@ namespace ServicePoint.BindGen public static extern BrightnessGrid* sp_brightness_grid_load(nuint width, nuint height, byte* data, nuint data_length); /// - /// 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`. @@ -259,19 +300,23 @@ namespace ServicePoint.BindGen public static extern BrightnessGrid* sp_brightness_grid_clone(BrightnessGrid* brightness_grid); /// - /// 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` + /// - `brightness_grid` was not passed to another consuming function, e.g. to create a [SPCommand] /// [DllImport(__DllName, EntryPoint = "sp_brightness_grid_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern void sp_brightness_grid_free(BrightnessGrid* brightness_grid); @@ -284,22 +329,25 @@ namespace ServicePoint.BindGen /// - `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 /// [DllImport(__DllName, EntryPoint = "sp_brightness_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern byte sp_brightness_grid_get(BrightnessGrid* brightness_grid, nuint x, nuint y); /// - /// Sets the value of the specified position in the `SPBrightnessGrid`. + /// Sets the value of the specified position in the [SPBrightnessGrid]. /// /// # Arguments /// @@ -311,6 +359,7 @@ namespace ServicePoint.BindGen /// /// # Panics /// + /// - when `brightness_grid` is NULL /// - When accessing `x` or `y` out of bounds. /// - When providing an invalid brightness value /// @@ -318,14 +367,14 @@ namespace ServicePoint.BindGen /// /// The caller has to make sure that: /// - /// - `brightness_grid` points to a valid `SPBitVec` + /// - `brightness_grid` points to a valid [SPBitVec] /// - `brightness_grid` is not written to or read from concurrently /// [DllImport(__DllName, EntryPoint = "sp_brightness_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern void sp_brightness_grid_set(BrightnessGrid* brightness_grid, nuint x, nuint y, byte value); /// - /// Sets the value of all cells in the `SPBrightnessGrid`. + /// Sets the value of all cells in the [SPBrightnessGrid]. /// /// # Arguments /// @@ -334,98 +383,127 @@ namespace ServicePoint.BindGen /// /// # 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 /// [DllImport(__DllName, EntryPoint = "sp_brightness_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern void sp_brightness_grid_fill(BrightnessGrid* brightness_grid, byte value); /// - /// 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] /// [DllImport(__DllName, EntryPoint = "sp_brightness_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern nuint sp_brightness_grid_width(BrightnessGrid* brightness_grid); /// - /// 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] /// [DllImport(__DllName, EntryPoint = "sp_brightness_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern nuint sp_brightness_grid_height(BrightnessGrid* brightness_grid); /// - /// 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`. /// - /// The caller has to make sure that: + /// # Panics /// - /// - `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 - /// - [DllImport(__DllName, EntryPoint = "sp_brightness_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteSlice sp_brightness_grid_unsafe_data_ref(BrightnessGrid* brightness_grid); - - /// - /// Tries to turn a `SPPacket` into a `SPCommand`. - /// - /// The packet is deallocated in the process. - /// - /// Returns: pointer to new `SPCommand` instance or NULL + /// - when `brightness_grid` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `SPPacket` points to a valid instance of `SPPacket` - /// - `SPPacket` is not used concurrently or after this call + /// - `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 + /// + [DllImport(__DllName, EntryPoint = "sp_brightness_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern ByteSlice sp_brightness_grid_unsafe_data_ref(BrightnessGrid* brightness_grid); + + /// + /// Tries to turn a [SPPacket] into a [SPCommand]. + /// + /// The packet is deallocated in the process. + /// + /// Returns: pointer to new [SPCommand] instance or NULL if parsing failed. + /// + /// # Panics + /// + /// - when `packet` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - [SPPacket] points to a valid instance of [SPPacket] + /// - [SPPacket] is not used concurrently or after this call /// - the result is checked for NULL - /// - 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`. /// [DllImport(__DllName, EntryPoint = "sp_command_try_from_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern Command* sp_command_try_from_packet(Packet* packet); /// - /// Clones a `SPCommand` instance. + /// Clones a [SPCommand] instance. + /// + /// returns: new [SPCommand] instance. Will never return NULL. + /// + /// # Panics + /// + /// - when `command` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `command` points to a valid instance of `SPCommand` + /// - `command` points to a valid instance of [SPCommand] /// - `command` is not written to concurrently - /// - 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`. /// [DllImport(__DllName, EntryPoint = "sp_command_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] @@ -436,7 +514,7 @@ namespace ServicePoint.BindGen /// /// Does not affect brightness. /// - /// Returns: a new `Command::Clear` instance. Will never return NULL. + /// Returns: a new [Command::Clear] instance. Will never return NULL. /// /// # Examples /// @@ -448,7 +526,7 @@ namespace ServicePoint.BindGen /// /// The caller has to make sure that: /// - /// - 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`. /// [DllImport(__DllName, EntryPoint = "sp_command_clear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] @@ -459,13 +537,13 @@ namespace ServicePoint.BindGen /// /// Please do not send this in your normal program flow. /// - /// Returns: a new `Command::HardReset` instance. Will never return NULL. + /// Returns: a new [Command::HardReset] instance. Will never return NULL. /// /// # Safety /// /// The caller has to make sure that: /// - /// - 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`. /// [DllImport(__DllName, EntryPoint = "sp_command_hard_reset", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] @@ -480,7 +558,7 @@ namespace ServicePoint.BindGen /// /// The caller has to make sure that: /// - /// - 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`. /// [DllImport(__DllName, EntryPoint = "sp_command_fade_out", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] @@ -489,7 +567,7 @@ namespace ServicePoint.BindGen /// /// Set the brightness of all tiles to the same value. /// - /// Returns: a new `Command::Brightness` instance. Will never return NULL. + /// Returns: a new [Command::Brightness] instance. Will never return NULL. /// /// # Panics /// @@ -499,7 +577,7 @@ namespace ServicePoint.BindGen /// /// The caller has to make sure that: /// - /// - 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`. /// [DllImport(__DllName, EntryPoint = "sp_command_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] @@ -508,17 +586,21 @@ namespace ServicePoint.BindGen /// /// 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. + /// + /// # Panics + /// + /// - when `grid` is NULL /// /// # Safety /// /// 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 + /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or /// by explicitly calling `sp_command_free`. /// [DllImport(__DllName, EntryPoint = "sp_command_char_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] @@ -530,20 +612,25 @@ namespace ServicePoint.BindGen /// The screen will continuously overwrite more pixel data without regarding the offset, meaning /// once the starting row is full, overwriting will continue on column 0. /// - /// The contained `SPBitVec` is always uncompressed. + /// The contained [SPBitVec] is always uncompressed. /// - /// The passed `SPBitVec` gets consumed. + /// The passed [SPBitVec] gets consumed. /// - /// Returns: a new `Command::BitmapLinear` instance. Will never return NULL. + /// Returns: a new [Command::BitmapLinear] instance. Will never return NULL. + /// + /// # Panics + /// + /// - when `bit_vec` is null + /// - when `compression_code` is not a valid value /// /// # Safety /// /// The caller has to make sure that: /// - /// - `bit_vec` points to a valid instance of `SPBitVec` + /// - `bit_vec` points to a valid instance of [SPBitVec] /// - `bit_vec` is not used concurrently or after this call /// - `compression` matches one of the allowed enum values - /// - 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`. /// [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] @@ -555,20 +642,25 @@ namespace ServicePoint.BindGen /// The screen will continuously overwrite more pixel data without regarding the offset, meaning /// once the starting row is full, overwriting will continue on column 0. /// - /// The contained `SPBitVec` is always uncompressed. + /// The contained [SPBitVec] is always uncompressed. /// - /// The passed `SPBitVec` gets consumed. + /// The passed [SPBitVec] gets consumed. /// - /// Returns: a new `Command::BitmapLinearAnd` instance. Will never return NULL. + /// Returns: a new [Command::BitmapLinearAnd] instance. Will never return NULL. + /// + /// # Panics + /// + /// - when `bit_vec` is null + /// - when `compression_code` is not a valid value /// /// # Safety /// /// The caller has to make sure that: /// - /// - `bit_vec` points to a valid instance of `SPBitVec` + /// - `bit_vec` points to a valid instance of [SPBitVec] /// - `bit_vec` is not used concurrently or after this call /// - `compression` matches one of the allowed enum values - /// - 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`. /// [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_and", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] @@ -580,20 +672,25 @@ namespace ServicePoint.BindGen /// The screen will continuously overwrite more pixel data without regarding the offset, meaning /// once the starting row is full, overwriting will continue on column 0. /// - /// The contained `SPBitVec` is always uncompressed. + /// The contained [SPBitVec] is always uncompressed. /// - /// The passed `SPBitVec` gets consumed. + /// The passed [SPBitVec] gets consumed. /// - /// Returns: a new `Command::BitmapLinearOr` instance. Will never return NULL. + /// Returns: a new [Command::BitmapLinearOr] instance. Will never return NULL. + /// + /// # Panics + /// + /// - when `bit_vec` is null + /// - when `compression_code` is not a valid value /// /// # Safety /// /// The caller has to make sure that: /// - /// - `bit_vec` points to a valid instance of `SPBitVec` + /// - `bit_vec` points to a valid instance of [SPBitVec] /// - `bit_vec` is not used concurrently or after this call /// - `compression` matches one of the allowed enum values - /// - 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`. /// [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_or", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] @@ -605,20 +702,25 @@ namespace ServicePoint.BindGen /// The screen will continuously overwrite more pixel data without regarding the offset, meaning /// once the starting row is full, overwriting will continue on column 0. /// - /// The contained `SPBitVec` is always uncompressed. + /// The contained [SPBitVec] is always uncompressed. /// - /// The passed `SPBitVec` gets consumed. + /// The passed [SPBitVec] gets consumed. /// - /// Returns: a new `Command::BitmapLinearXor` instance. Will never return NULL. + /// Returns: a new [Command::BitmapLinearXor] instance. Will never return NULL. + /// + /// # Panics + /// + /// - when `bit_vec` is null + /// - when `compression_code` is not a valid value /// /// # Safety /// /// The caller has to make sure that: /// - /// - `bit_vec` points to a valid instance of `SPBitVec` + /// - `bit_vec` points to a valid instance of [SPBitVec] /// - `bit_vec` is not used concurrently or after this call /// - `compression` matches one of the allowed enum values - /// - 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`. /// [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_xor", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] @@ -627,22 +729,21 @@ namespace ServicePoint.BindGen /// /// Show text on the screen. /// - /// <div class="warning"> - /// The library does not currently convert between UTF-8 and CP-437. - /// Because Rust expects UTF-8 strings, it might be necessary to only send ASCII for now. - /// </div> + /// The passed [SPCp437Grid] gets consumed. /// - /// The passed `SPCp437Grid` gets consumed./// + /// Returns: a new [Command::Cp437Data] instance. Will never return NULL. /// - /// Returns: a new `Command::Cp437Data` instance. Will never return NULL. + /// # Panics + /// + /// - when `grid` is null /// /// # Safety /// /// The caller has to make sure that: /// - /// - `grid` points to a valid instance of `SPCp437Grid` + /// - `grid` points to a valid instance of [SPCp437Grid] /// - `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`. /// [DllImport(__DllName, EntryPoint = "sp_command_cp437_data", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] @@ -651,25 +752,30 @@ namespace ServicePoint.BindGen /// /// Sets a window of pixels to the specified values. /// - /// The passed `SPPixelGrid` gets consumed. + /// The passed [SPPixelGrid] gets consumed. /// - /// Returns: a new `Command::BitmapLinearWin` instance. Will never return NULL. + /// Returns: a new [Command::BitmapLinearWin] instance. Will never return NULL. + /// + /// # Panics + /// + /// - when `pixel_grid` is null + /// - when `compression_code` is not a valid value /// /// # Safety /// /// The caller has to make sure that: /// - /// - `pixel_grid` points to a valid instance of `SPPixelGrid` + /// - `pixel_grid` points to a valid instance of [SPPixelGrid] /// - `pixel_grid` is not used concurrently or after this call /// - `compression` matches one of the allowed enum values - /// - 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`. /// [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_win", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern Command* sp_command_bitmap_linear_win(nuint x, nuint y, PixelGrid* pixel_grid, CompressionCode compression_code); /// - /// Deallocates a `SPCommand`. + /// Deallocates a [SPCommand]. /// /// # Examples /// @@ -678,25 +784,29 @@ namespace ServicePoint.BindGen /// sp_command_free(c); /// ``` /// + /// # Panics + /// + /// - when `command` is NULL + /// /// # Safety /// /// The caller has to make sure that: /// - /// - `command` points to a valid `SPCommand` + /// - `command` points to a valid [SPCommand] /// - `command` is not used concurrently or after this call - /// - `command` was not passed to another consuming function, e.g. to create a `SPPacket` + /// - `command` was not passed to another consuming function, e.g. to create a [SPPacket] /// [DllImport(__DllName, EntryPoint = "sp_command_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern void sp_command_free(Command* command); /// - /// Creates a new instance of `SPConnection`. + /// Creates a new instance of [SPConnection]. /// /// returns: NULL if connection fails, or connected instance /// /// # Panics /// - /// Bad string encoding + /// - when `host` is null or an invalid host /// /// # Safety /// @@ -709,18 +819,23 @@ namespace ServicePoint.BindGen public static extern Connection* sp_connection_open(byte* host); /// - /// Sends a `SPPacket` to the display using the `SPConnection`. + /// Sends a [SPPacket] to the display using the [SPConnection]. /// /// The passed `packet` gets consumed. /// /// returns: true in case of success /// + /// # Panics + /// + /// - when `connection` is NULL + /// - when `packet` is NULL + /// /// # Safety /// /// The caller has to make sure that: /// - /// - `connection` points to a valid instance of `SPConnection` - /// - `packet` points to a valid instance of `SPPacket` + /// - `connection` points to a valid instance of [SPConnection] + /// - `packet` points to a valid instance of [SPPacket] /// - `packet` is not used concurrently or after this call /// [DllImport(__DllName, EntryPoint = "sp_connection_send_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] @@ -728,18 +843,23 @@ namespace ServicePoint.BindGen public static extern bool sp_connection_send_packet(Connection* connection, Packet* packet); /// - /// Sends a `SPCommand` to the display using the `SPConnection`. + /// Sends a [SPCommand] to the display using the [SPConnection]. /// /// The passed `command` gets consumed. /// /// returns: true in case of success /// + /// # Panics + /// + /// - when `connection` is NULL + /// - when `command` is NULL + /// /// # Safety /// /// The caller has to make sure that: /// - /// - `connection` points to a valid instance of `SPConnection` - /// - `command` points to a valid instance of `SPPacket` + /// - `connection` points to a valid instance of [SPConnection] + /// - `command` points to a valid instance of [SPPacket] /// - `command` is not used concurrently or after this call /// [DllImport(__DllName, EntryPoint = "sp_connection_send_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] @@ -747,22 +867,26 @@ namespace ServicePoint.BindGen public static extern bool sp_connection_send_command(Connection* connection, Command* command); /// - /// Closes and deallocates a `SPConnection`. + /// Closes and deallocates a [SPConnection]. + /// + /// # Panics + /// + /// - when `connection` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `connection` points to a valid `SPConnection` + /// - `connection` points to a valid [SPConnection] /// - `connection` is not used concurrently or after this call /// [DllImport(__DllName, EntryPoint = "sp_connection_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern void sp_connection_free(Connection* connection); /// - /// Creates a new `SPCp437Grid` with the specified dimensions. + /// Creates a new [SPCp437Grid] with the specified dimensions. /// - /// returns: `SPCp437Grid` initialized to 0. + /// returns: [SPCp437Grid] initialized to 0. Will never return NULL. /// /// # Safety /// @@ -775,13 +899,14 @@ namespace ServicePoint.BindGen public static extern Cp437Grid* sp_cp437_grid_new(nuint width, nuint height); /// - /// Loads a `SPCp437Grid` with the specified dimensions from the provided data. + /// Loads a [SPCp437Grid] with the specified dimensions from the provided data. /// /// 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 /// @@ -796,15 +921,19 @@ namespace ServicePoint.BindGen public static extern Cp437Grid* sp_cp437_grid_load(nuint width, nuint height, byte* data, nuint data_length); /// - /// Clones a `SPCp437Grid`. + /// Clones a [SPCp437Grid]. /// /// Will never return NULL. /// + /// # Panics + /// + /// - when `cp437_grid` is NULL + /// /// # Safety /// /// The caller has to make sure that: /// - /// - `cp437_grid` points to a valid `SPCp437Grid` + /// - `cp437_grid` points to a valid [SPCp437Grid] /// - `cp437_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_cp437_grid_free`. @@ -813,15 +942,19 @@ namespace ServicePoint.BindGen public static extern Cp437Grid* sp_cp437_grid_clone(Cp437Grid* cp437_grid); /// - /// Deallocates a `SPCp437Grid`. + /// Deallocates a [SPCp437Grid]. + /// + /// # Panics + /// + /// - when `cp437_grid` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `cp437_grid` points to a valid `SPCp437Grid` + /// - `cp437_grid` points to a valid [SPCp437Grid] /// - `cp437_grid` is not used concurrently or after cp437_grid call - /// - `cp437_grid` was not passed to another consuming function, e.g. to create a `SPCommand` + /// - `cp437_grid` was not passed to another consuming function, e.g. to create a [SPCommand] /// [DllImport(__DllName, EntryPoint = "sp_cp437_grid_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern void sp_cp437_grid_free(Cp437Grid* cp437_grid); @@ -836,20 +969,21 @@ namespace ServicePoint.BindGen /// /// # Panics /// - /// When accessing `x` or `y` out of bounds. + /// - when `cp437_grid` is NULL + /// - when accessing `x` or `y` out of bounds /// /// # Safety /// /// The caller has to make sure that: /// - /// - `cp437_grid` points to a valid `SPCp437Grid` + /// - `cp437_grid` points to a valid [SPCp437Grid] /// - `cp437_grid` is not written to concurrently /// [DllImport(__DllName, EntryPoint = "sp_cp437_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern byte sp_cp437_grid_get(Cp437Grid* cp437_grid, nuint x, nuint y); /// - /// Sets the value of the specified position in the `SPCp437Grid`. + /// Sets the value of the specified position in the [SPCp437Grid]. /// /// # Arguments /// @@ -861,129 +995,158 @@ namespace ServicePoint.BindGen /// /// # Panics /// - /// When accessing `x` or `y` out of bounds. + /// - when `cp437_grid` is NULL + /// - when accessing `x` or `y` out of bounds /// /// # Safety /// /// The caller has to make sure that: /// - /// - `cp437_grid` points to a valid `SPBitVec` + /// - `cp437_grid` points to a valid [SPBitVec] /// - `cp437_grid` is not written to or read from concurrently /// [DllImport(__DllName, EntryPoint = "sp_cp437_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern void sp_cp437_grid_set(Cp437Grid* cp437_grid, nuint x, nuint y, byte value); /// - /// Sets the value of all cells in the `SPCp437Grid`. + /// Sets the value of all cells in the [SPCp437Grid]. /// /// # Arguments /// /// - `cp437_grid`: instance to write to /// - `value`: the value to set all cells to /// + /// # Panics + /// + /// - when `cp437_grid` is NULL + /// /// # Safety /// /// The caller has to make sure that: /// - /// - `cp437_grid` points to a valid `SPCp437Grid` + /// - `cp437_grid` points to a valid [SPCp437Grid] /// - `cp437_grid` is not written to or read from concurrently /// [DllImport(__DllName, EntryPoint = "sp_cp437_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern void sp_cp437_grid_fill(Cp437Grid* cp437_grid, byte value); /// - /// Gets the width of the `SPCp437Grid` instance. + /// Gets the width of the [SPCp437Grid] instance. /// /// # Arguments /// /// - `cp437_grid`: instance to read from /// + /// # Panics + /// + /// - when `cp437_grid` is NULL + /// /// # Safety /// /// The caller has to make sure that: /// - /// - `cp437_grid` points to a valid `SPCp437Grid` + /// - `cp437_grid` points to a valid [SPCp437Grid] /// [DllImport(__DllName, EntryPoint = "sp_cp437_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern nuint sp_cp437_grid_width(Cp437Grid* cp437_grid); /// - /// Gets the height of the `SPCp437Grid` instance. + /// Gets the height of the [SPCp437Grid] instance. /// /// # Arguments /// /// - `cp437_grid`: instance to read from /// + /// # Panics + /// + /// - when `cp437_grid` is NULL + /// /// # Safety /// /// The caller has to make sure that: /// - /// - `cp437_grid` points to a valid `SPCp437Grid` + /// - `cp437_grid` points to a valid [SPCp437Grid] /// [DllImport(__DllName, EntryPoint = "sp_cp437_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern nuint sp_cp437_grid_height(Cp437Grid* cp437_grid); /// - /// Gets an unsafe reference to the data of the `SPCp437Grid` instance. + /// Gets an unsafe reference to the data of the [SPCp437Grid] instance. /// /// Will never return NULL. /// + /// # Panics + /// + /// - when `cp437_grid` is NULL + /// /// ## Safety /// /// The caller has to make sure that: /// - /// - `cp437_grid` points to a valid `SPCp437Grid` - /// - the returned memory range is never accessed after the passed `SPCp437Grid` has been freed - /// - the returned memory range is never accessed concurrently, either via the `SPCp437Grid` or directly + /// - `cp437_grid` points to a valid [SPCp437Grid] + /// - the returned memory range is never accessed after the passed [SPCp437Grid] has been freed + /// - the returned memory range is never accessed concurrently, either via the [SPCp437Grid] or directly /// [DllImport(__DllName, EntryPoint = "sp_cp437_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern ByteSlice sp_cp437_grid_unsafe_data_ref(Cp437Grid* cp437_grid); /// - /// Turns a `SPCommand` into a `SPPacket`. - /// The `SPCommand` gets consumed. + /// Turns a [SPCommand] into a [SPPacket]. + /// The [SPCommand] gets consumed. /// /// Will never return NULL. /// + /// # Panics + /// + /// - when `command` is NULL + /// /// # Safety /// /// The caller has to make sure that: /// - /// - `SPCommand` points to a valid instance of `SPCommand` - /// - `SPCommand` is not used concurrently or after this call - /// - the returned `SPPacket` instance is freed in some way, either by using a consuming function or + /// - [SPCommand] points to a valid instance of [SPCommand] + /// - [SPCommand] is not used concurrently or after this call + /// - the returned [SPPacket] instance is freed in some way, either by using a consuming function or /// by explicitly calling `sp_packet_free`. /// [DllImport(__DllName, EntryPoint = "sp_packet_from_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern Packet* sp_packet_from_command(Command* command); /// - /// 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. /// /// returns: NULL in case of an error, pointer to the allocated packet otherwise /// + /// # Panics + /// + /// - when `data` is NULL + /// /// # Safety /// /// The caller has to make sure that: /// /// - `data` points to a valid memory region of at least `length` bytes /// - `data` is not written to concurrently - /// - the returned `SPPacket` instance is freed in some way, either by using a consuming function or + /// - the returned [SPPacket] instance is freed in some way, either by using a consuming function or /// by explicitly calling `sp_packet_free`. /// [DllImport(__DllName, EntryPoint = "sp_packet_try_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern Packet* sp_packet_try_load(byte* data, nuint length); /// - /// Clones a `SPPacket`. + /// Clones a [SPPacket]. /// /// Will never return NULL. /// + /// # Panics + /// + /// - when `packet` is NULL + /// /// # Safety /// /// The caller has to make sure that: /// - /// - `packet` points to a valid `SPPacket` + /// - `packet` points to a valid [SPPacket] /// - `packet` is not written to concurrently /// - the returned instance is freed in some way, either by using a consuming function or /// by explicitly calling `sp_packet_free`. @@ -992,27 +1155,31 @@ namespace ServicePoint.BindGen public static extern Packet* sp_packet_clone(Packet* packet); /// - /// Deallocates a `SPPacket`. + /// Deallocates a [SPPacket]. + /// + /// # Panics + /// + /// - when `sp_packet_free` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `packet` points to a valid `SPPacket` + /// - `packet` points to a valid [SPPacket] /// - `packet` is not used concurrently or after this call /// [DllImport(__DllName, EntryPoint = "sp_packet_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern void sp_packet_free(Packet* packet); /// - /// Creates a new `SPPixelGrid` with the specified dimensions. + /// Creates a new [SPPixelGrid] with the specified dimensions. /// /// # Arguments /// /// - `width`: size in pixels in x-direction /// - `height`: size in pixels in y-direction /// - /// returns: `SPPixelGrid` initialized to all pixels off. Will never return NULL. + /// returns: [SPPixelGrid] initialized to all pixels off. Will never return NULL. /// /// # Panics /// @@ -1029,17 +1196,18 @@ namespace ServicePoint.BindGen public static extern PixelGrid* sp_pixel_grid_new(nuint width, nuint height); /// - /// Loads a `SPPixelGrid` with the specified dimensions from the provided data. + /// Loads a [SPPixelGrid] with the specified dimensions from the provided data. /// /// # Arguments /// /// - `width`: size in pixels in x-direction /// - `height`: size in pixels in y-direction /// - /// returns: `SPPixelGrid` that contains a copy of the provided data. Will never return NULL. + /// returns: [SPPixelGrid] that contains a copy of the provided data. Will never return NULL. /// /// # Panics /// + /// - when `data` is NULL /// - when the dimensions and data size do not match exactly. /// - when the width is not dividable by 8 /// @@ -1055,15 +1223,19 @@ namespace ServicePoint.BindGen public static extern PixelGrid* sp_pixel_grid_load(nuint width, nuint height, byte* data, nuint data_length); /// - /// Clones a `SPPixelGrid`. + /// Clones a [SPPixelGrid]. /// /// Will never return NULL. /// + /// # Panics + /// + /// - when `pixel_grid` is NULL + /// /// # Safety /// /// The caller has to make sure that: /// - /// - `pixel_grid` points to a valid `SPPixelGrid` + /// - `pixel_grid` points to a valid [SPPixelGrid] /// - `pixel_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_pixel_grid_free`. @@ -1072,21 +1244,25 @@ namespace ServicePoint.BindGen public static extern PixelGrid* sp_pixel_grid_clone(PixelGrid* pixel_grid); /// - /// Deallocates a `SPPixelGrid`. + /// Deallocates a [SPPixelGrid]. + /// + /// # Panics + /// + /// - when `pixel_grid` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `pixel_grid` points to a valid `SPPixelGrid` + /// - `pixel_grid` points to a valid [SPPixelGrid] /// - `pixel_grid` is not used concurrently or after pixel_grid call - /// - `pixel_grid` was not passed to another consuming function, e.g. to create a `SPCommand` + /// - `pixel_grid` was not passed to another consuming function, e.g. to create a [SPCommand] /// [DllImport(__DllName, EntryPoint = "sp_pixel_grid_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern void sp_pixel_grid_free(PixelGrid* pixel_grid); /// - /// Gets the current value at the specified position in the `SPPixelGrid`. + /// Gets the current value at the specified position in the [SPPixelGrid]. /// /// # Arguments /// @@ -1095,13 +1271,14 @@ namespace ServicePoint.BindGen /// /// # Panics /// - /// When accessing `x` or `y` out of bounds. + /// - when `pixel_grid` is NULL + /// - when accessing `x` or `y` out of bounds /// /// # Safety /// /// The caller has to make sure that: /// - /// - `pixel_grid` points to a valid `SPPixelGrid` + /// - `pixel_grid` points to a valid [SPPixelGrid] /// - `pixel_grid` is not written to concurrently /// [DllImport(__DllName, EntryPoint = "sp_pixel_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] @@ -1109,7 +1286,7 @@ namespace ServicePoint.BindGen public static extern bool sp_pixel_grid_get(PixelGrid* pixel_grid, nuint x, nuint y); /// - /// Sets the value of the specified position in the `SPPixelGrid`. + /// Sets the value of the specified position in the [SPPixelGrid]. /// /// # Arguments /// @@ -1121,78 +1298,95 @@ namespace ServicePoint.BindGen /// /// # Panics /// - /// When accessing `x` or `y` out of bounds. + /// - when `pixel_grid` is NULL + /// - when accessing `x` or `y` out of bounds /// /// # Safety /// /// The caller has to make sure that: /// - /// - `pixel_grid` points to a valid `SPPixelGrid` + /// - `pixel_grid` points to a valid [SPPixelGrid] /// - `pixel_grid` is not written to or read from concurrently /// [DllImport(__DllName, EntryPoint = "sp_pixel_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern void sp_pixel_grid_set(PixelGrid* pixel_grid, nuint x, nuint y, [MarshalAs(UnmanagedType.U1)] bool value); /// - /// Sets the state of all pixels in the `SPPixelGrid`. + /// Sets the state of all pixels in the [SPPixelGrid]. /// /// # Arguments /// /// - `pixel_grid`: instance to write to /// - `value`: the value to set all pixels to /// + /// # Panics + /// + /// - when `pixel_grid` is NULL + /// /// # Safety /// /// The caller has to make sure that: /// - /// - `pixel_grid` points to a valid `SPPixelGrid` + /// - `pixel_grid` points to a valid [SPPixelGrid] /// - `pixel_grid` is not written to or read from concurrently /// [DllImport(__DllName, EntryPoint = "sp_pixel_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern void sp_pixel_grid_fill(PixelGrid* pixel_grid, [MarshalAs(UnmanagedType.U1)] bool value); /// - /// Gets the width in pixels of the `SPPixelGrid` instance. + /// Gets the width in pixels of the [SPPixelGrid] instance. /// /// # Arguments /// /// - `pixel_grid`: instance to read from /// + /// # Panics + /// + /// - when `pixel_grid` is NULL + /// /// # Safety /// /// The caller has to make sure that: /// - /// - `pixel_grid` points to a valid `SPPixelGrid` + /// - `pixel_grid` points to a valid [SPPixelGrid] /// [DllImport(__DllName, EntryPoint = "sp_pixel_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern nuint sp_pixel_grid_width(PixelGrid* pixel_grid); /// - /// Gets the height in pixels of the `SPPixelGrid` instance. + /// Gets the height in pixels of the [SPPixelGrid] instance. /// /// # Arguments /// /// - `pixel_grid`: instance to read from /// + /// # Panics + /// + /// - when `pixel_grid` is NULL + /// /// # Safety /// /// The caller has to make sure that: /// - /// - `pixel_grid` points to a valid `SPPixelGrid` + /// - `pixel_grid` points to a valid [SPPixelGrid] /// [DllImport(__DllName, EntryPoint = "sp_pixel_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern nuint sp_pixel_grid_height(PixelGrid* pixel_grid); /// - /// Gets an unsafe reference to the data of the `SPPixelGrid` instance. + /// Gets an unsafe reference to the data of the [SPPixelGrid] instance. /// - /// ## Safety + /// # Panics + /// + /// - when `pixel_grid` is NULL + /// + /// # Safety /// /// The caller has to make sure that: /// - /// - `pixel_grid` points to a valid `SPPixelGrid` - /// - the returned memory range is never accessed after the passed `SPPixelGrid` has been freed - /// - the returned memory range is never accessed concurrently, either via the `SPPixelGrid` or directly + /// - `pixel_grid` points to a valid [SPPixelGrid] + /// - the returned memory range is never accessed after the passed [SPPixelGrid] has been freed + /// - the returned memory range is never accessed concurrently, either via the [SPPixelGrid] or directly /// [DllImport(__DllName, EntryPoint = "sp_pixel_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern ByteSlice sp_pixel_grid_unsafe_data_ref(PixelGrid* pixel_grid); From bd0ecd77d2322dadf59f2e925545db1ca1a5301b Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Mon, 14 Oct 2024 22:42:45 +0200 Subject: [PATCH 14/27] rename PixelGrid to Bitmap --- .../examples/brightness_tester.rs | 2 +- crates/servicepoint/examples/game_of_life.rs | 8 +- crates/servicepoint/examples/moving_line.rs | 2 +- .../examples/random_brightness.rs | 2 +- crates/servicepoint/examples/websocket.rs | 4 +- crates/servicepoint/examples/wiping_clear.rs | 2 +- .../src/{pixel_grid.rs => bitmap.rs} | 78 +- crates/servicepoint/src/command.rs | 18 +- crates/servicepoint/src/compression_code.rs | 6 +- crates/servicepoint/src/lib.rs | 22 +- crates/servicepoint/src/packet.rs | 6 +- crates/servicepoint_binding_c/README.md | 4 +- .../examples/lang_c/include/servicepoint.h | 469 +++++----- .../examples/lang_c/src/main.c | 4 +- crates/servicepoint_binding_c/src/bitmap.rs | 290 +++++++ crates/servicepoint_binding_c/src/command.rs | 16 +- crates/servicepoint_binding_c/src/lib.rs | 8 +- .../servicepoint_binding_c/src/pixel_grid.rs | 290 ------- crates/servicepoint_binding_cs/README.md | 2 +- .../ServicePoint/BindGen/ServicePoint.g.cs | 810 +++++++++--------- .../ServicePoint/{PixelGrid.cs => Bitmap.cs} | 30 +- .../ServicePoint/Command.cs | 4 +- .../examples/lang_cs/Program.cs | 2 +- 23 files changed, 1037 insertions(+), 1042 deletions(-) rename crates/servicepoint/src/{pixel_grid.rs => bitmap.rs} (74%) create mode 100644 crates/servicepoint_binding_c/src/bitmap.rs delete mode 100644 crates/servicepoint_binding_c/src/pixel_grid.rs rename crates/servicepoint_binding_cs/ServicePoint/{PixelGrid.cs => Bitmap.cs} (50%) diff --git a/crates/servicepoint/examples/brightness_tester.rs b/crates/servicepoint/examples/brightness_tester.rs index 5f2bd90..16fbf61 100644 --- a/crates/servicepoint/examples/brightness_tester.rs +++ b/crates/servicepoint/examples/brightness_tester.rs @@ -15,7 +15,7 @@ fn main() { let connection = Connection::open(cli.destination) .expect("could not connect to display"); - let mut pixels = PixelGrid::max_sized(); + let mut pixels = Bitmap::max_sized(); pixels.fill(true); let command = Command::BitmapLinearWin( diff --git a/crates/servicepoint/examples/game_of_life.rs b/crates/servicepoint/examples/game_of_life.rs index 29507ce..3a72f4e 100644 --- a/crates/servicepoint/examples/game_of_life.rs +++ b/crates/servicepoint/examples/game_of_life.rs @@ -34,7 +34,7 @@ fn main() { } } -fn iteration(field: PixelGrid) -> PixelGrid { +fn iteration(field: Bitmap) -> Bitmap { let mut next = field.clone(); for x in 0..field.width() { for y in 0..field.height() { @@ -51,7 +51,7 @@ fn iteration(field: PixelGrid) -> PixelGrid { next } -fn count_neighbors(field: &PixelGrid, x: i32, y: i32) -> i32 { +fn count_neighbors(field: &Bitmap, x: i32, y: i32) -> i32 { let mut count = 0; for nx in x - 1..=x + 1 { for ny in y - 1..=y + 1 { @@ -78,8 +78,8 @@ fn count_neighbors(field: &PixelGrid, x: i32, y: i32) -> i32 { count } -fn make_random_field(probability: f64) -> PixelGrid { - let mut field = PixelGrid::max_sized(); +fn make_random_field(probability: f64) -> Bitmap { + let mut field = Bitmap::max_sized(); let mut rng = rand::thread_rng(); let d = distributions::Bernoulli::new(probability).unwrap(); for x in 0..field.width() { diff --git a/crates/servicepoint/examples/moving_line.rs b/crates/servicepoint/examples/moving_line.rs index 5682be4..3e55104 100644 --- a/crates/servicepoint/examples/moving_line.rs +++ b/crates/servicepoint/examples/moving_line.rs @@ -16,7 +16,7 @@ fn main() { let connection = Connection::open(Cli::parse().destination) .expect("could not connect to display"); - let mut pixels = PixelGrid::max_sized(); + let mut pixels = Bitmap::max_sized(); for x_offset in 0..usize::MAX { pixels.fill(false); diff --git a/crates/servicepoint/examples/random_brightness.rs b/crates/servicepoint/examples/random_brightness.rs index 01487a2..51ab515 100644 --- a/crates/servicepoint/examples/random_brightness.rs +++ b/crates/servicepoint/examples/random_brightness.rs @@ -28,7 +28,7 @@ fn main() { // put all pixels in on state if cli.enable_all { - let mut filled_grid = PixelGrid::max_sized(); + let mut filled_grid = Bitmap::max_sized(); filled_grid.fill(true); let command = BitmapLinearWin( diff --git a/crates/servicepoint/examples/websocket.rs b/crates/servicepoint/examples/websocket.rs index 71be6a3..b982633 100644 --- a/crates/servicepoint/examples/websocket.rs +++ b/crates/servicepoint/examples/websocket.rs @@ -1,7 +1,7 @@ //! Example for how to use the WebSocket connection use servicepoint::{ - Command, CompressionCode, Connection, Grid, Origin, PixelGrid, + Command, CompressionCode, Connection, Grid, Origin, Bitmap, }; fn main() { @@ -13,7 +13,7 @@ fn main() { // use send_mut instead of send connection.send_mut(Command::Clear).unwrap(); - let mut pixels = PixelGrid::max_sized(); + let mut pixels = Bitmap::max_sized(); pixels.fill(true); // use send_mut instead of send diff --git a/crates/servicepoint/examples/wiping_clear.rs b/crates/servicepoint/examples/wiping_clear.rs index 03e8215..c28345d 100644 --- a/crates/servicepoint/examples/wiping_clear.rs +++ b/crates/servicepoint/examples/wiping_clear.rs @@ -25,7 +25,7 @@ fn main() { let connection = Connection::open(cli.destination) .expect("could not connect to display"); - let mut enabled_pixels = PixelGrid::new(PIXEL_WIDTH, PIXEL_HEIGHT); + let mut enabled_pixels = Bitmap::new(PIXEL_WIDTH, PIXEL_HEIGHT); enabled_pixels.fill(true); for x_offset in 0..PIXEL_WIDTH { diff --git a/crates/servicepoint/src/pixel_grid.rs b/crates/servicepoint/src/bitmap.rs similarity index 74% rename from crates/servicepoint/src/pixel_grid.rs rename to crates/servicepoint/src/bitmap.rs index 746f2ac..9eabf96 100644 --- a/crates/servicepoint/src/pixel_grid.rs +++ b/crates/servicepoint/src/bitmap.rs @@ -6,21 +6,21 @@ use crate::{BitVec, DataRef, Grid, SpBitVec, PIXEL_HEIGHT, PIXEL_WIDTH}; /// A grid of pixels stored in packed bytes. #[derive(Debug, Clone, PartialEq)] -pub struct PixelGrid { +pub struct Bitmap { width: usize, height: usize, bit_vec: SpBitVec, } -impl PixelGrid { - /// Creates a new [PixelGrid] with the specified dimensions. +impl Bitmap { + /// Creates a new [Bitmap] with the specified dimensions. /// /// # Arguments /// /// - `width`: size in pixels in x-direction /// - `height`: size in pixels in y-direction /// - /// returns: [PixelGrid] initialized to all pixels off + /// returns: [Bitmap] initialized to all pixels off /// /// # Panics /// @@ -40,14 +40,14 @@ impl PixelGrid { Self::new(PIXEL_WIDTH, PIXEL_HEIGHT) } - /// Loads a [PixelGrid] with the specified dimensions from the provided data. + /// Loads a [Bitmap] with the specified dimensions from the provided data. /// /// # Arguments /// /// - `width`: size in pixels in x-direction /// - `height`: size in pixels in y-direction /// - /// returns: [PixelGrid] that contains a copy of the provided data + /// returns: [Bitmap] that contains a copy of the provided data /// /// # Panics /// @@ -64,12 +64,12 @@ impl PixelGrid { } } - /// Iterate over all cells in [PixelGrid]. + /// Iterate over all cells in [Bitmap]. /// /// Order is equivalent to the following loop: /// ``` - /// # use servicepoint::{PixelGrid, Grid}; - /// # let grid = PixelGrid::new(8,2); + /// # use servicepoint::{Bitmap, Grid}; + /// # let grid = Bitmap::new(8,2); /// for y in 0..grid.height() { /// for x in 0..grid.width() { /// grid.get(x, y); @@ -80,12 +80,12 @@ impl PixelGrid { self.bit_vec.iter().by_refs() } - /// Iterate over all cells in [PixelGrid] mutably. + /// Iterate over all cells in [Bitmap] mutably. /// /// Order is equivalent to the following loop: /// ``` - /// # use servicepoint::{PixelGrid, Grid}; - /// # let mut grid = PixelGrid::new(8,2); + /// # use servicepoint::{Bitmap, Grid}; + /// # let mut grid = Bitmap::new(8,2); /// # let value = false; /// for y in 0..grid.height() { /// for x in 0..grid.width() { @@ -96,8 +96,8 @@ impl PixelGrid { /// /// # Example /// ``` - /// # use servicepoint::{PixelGrid, Grid}; - /// # let mut grid = PixelGrid::new(8,2); + /// # use servicepoint::{Bitmap, Grid}; + /// # let mut grid = Bitmap::new(8,2); /// # let value = false; /// for (index, mut pixel) in grid.iter_mut().enumerate() { /// pixel.set(index % 2 == 0) @@ -107,17 +107,17 @@ impl PixelGrid { self.bit_vec.iter_mut() } - /// Iterate over all rows in [PixelGrid] top to bottom. + /// Iterate over all rows in [Bitmap] top to bottom. pub fn iter_rows(&self) -> IterRows { IterRows { - pixel_grid: self, + bitmap: self, row: 0, } } } -impl Grid for PixelGrid { - /// Sets the value of the specified position in the [PixelGrid]. +impl Grid for Bitmap { + /// Sets the value of the specified position in the [Bitmap]. /// /// # Arguments /// @@ -139,7 +139,7 @@ impl Grid for PixelGrid { self.bit_vec[x + y * self.width] } - /// Sets the state of all pixels in the [PixelGrid]. + /// Sets the state of all pixels in the [Bitmap]. /// /// # Arguments /// @@ -158,7 +158,7 @@ impl Grid for PixelGrid { } } -impl DataRef for PixelGrid { +impl DataRef for Bitmap { fn data_ref_mut(&mut self) -> &mut [u8] { self.bit_vec.as_raw_mut_slice() } @@ -168,15 +168,15 @@ impl DataRef for PixelGrid { } } -impl From for Vec { - /// Turns a [PixelGrid] into the underlying [`Vec`]. - fn from(value: PixelGrid) -> Self { +impl From for Vec { + /// Turns a [Bitmap] into the underlying [`Vec`]. + fn from(value: Bitmap) -> Self { value.bit_vec.into() } } pub struct IterRows<'t> { - pixel_grid: &'t PixelGrid, + bitmap: &'t Bitmap, row: usize, } @@ -184,24 +184,24 @@ impl<'t> Iterator for IterRows<'t> { type Item = &'t BitSlice; fn next(&mut self) -> Option { - if self.row >= self.pixel_grid.height { + if self.row >= self.bitmap.height { return None; } - let start = self.row * self.pixel_grid.width; - let end = start + self.pixel_grid.width; + let start = self.row * self.bitmap.width; + let end = start + self.bitmap.width; self.row += 1; - Some(&self.pixel_grid.bit_vec[start..end]) + Some(&self.bitmap.bit_vec[start..end]) } } #[cfg(test)] mod tests { - use crate::{DataRef, Grid, PixelGrid}; + use crate::{DataRef, Grid, Bitmap}; #[test] fn fill() { - let mut grid = PixelGrid::new(8, 2); + let mut grid = Bitmap::new(8, 2); assert_eq!(grid.data_ref(), [0x00, 0x00]); grid.fill(true); @@ -213,7 +213,7 @@ mod tests { #[test] fn get_set() { - let mut grid = PixelGrid::new(8, 2); + let mut grid = Bitmap::new(8, 2); assert!(!grid.get(0, 0)); assert!(!grid.get(1, 1)); @@ -228,7 +228,7 @@ mod tests { #[test] fn load() { - let mut grid = PixelGrid::new(8, 3); + let mut grid = Bitmap::new(8, 3); for x in 0..grid.width { for y in 0..grid.height { grid.set(x, y, (x + y) % 2 == 0); @@ -239,33 +239,33 @@ mod tests { let data: Vec = grid.into(); - let grid = PixelGrid::load(8, 3, &data); + let grid = Bitmap::load(8, 3, &data); assert_eq!(grid.data_ref(), [0xAA, 0x55, 0xAA]); } #[test] #[should_panic] fn out_of_bounds_x() { - let vec = PixelGrid::new(8, 2); + let vec = Bitmap::new(8, 2); vec.get(8, 1); } #[test] #[should_panic] fn out_of_bounds_y() { - let mut vec = PixelGrid::new(8, 2); + let mut vec = Bitmap::new(8, 2); vec.set(1, 2, false); } #[test] fn iter() { - let grid = PixelGrid::new(8, 2); + let grid = Bitmap::new(8, 2); assert_eq!(16, grid.iter().count()) } #[test] fn iter_rows() { - let grid = PixelGrid::load(8, 2, &[0x04, 0x40]); + let grid = Bitmap::load(8, 2, &[0x04, 0x40]); let mut iter = grid.iter_rows(); assert_eq!(iter.next().unwrap().count_ones(), 1); @@ -275,7 +275,7 @@ mod tests { #[test] fn iter_mut() { - let mut grid = PixelGrid::new(8, 2); + let mut grid = Bitmap::new(8, 2); for (index, mut pixel) in grid.iter_mut().enumerate() { pixel.set(index % 2 == 0); } @@ -284,7 +284,7 @@ mod tests { #[test] fn data_ref_mut() { - let mut grid = PixelGrid::new(8, 2); + let mut grid = Bitmap::new(8, 2); let data = grid.data_ref_mut(); data[1] = 0x0F; assert!(grid.get(7, 1)); diff --git a/crates/servicepoint/src/command.rs b/crates/servicepoint/src/command.rs index 210ab01..94a161a 100644 --- a/crates/servicepoint/src/command.rs +++ b/crates/servicepoint/src/command.rs @@ -4,7 +4,7 @@ use crate::{ command_code::CommandCode, compression::into_decompressed, packet::{Header, Packet}, - Brightness, BrightnessGrid, CompressionCode, Cp437Grid, Origin, PixelGrid, + Brightness, BrightnessGrid, CompressionCode, Cp437Grid, Origin, Bitmap, Pixels, PrimitiveGrid, SpBitVec, Tiles, TILE_SIZE, }; @@ -105,10 +105,10 @@ pub enum Command { /// # Examples /// /// ```rust - /// # use servicepoint::{Command, CompressionCode, Grid, PixelGrid}; + /// # use servicepoint::{Command, CompressionCode, Grid, Bitmap}; /// # let connection = servicepoint::Connection::Fake; /// # - /// let mut pixels = PixelGrid::max_sized(); + /// let mut pixels = Bitmap::max_sized(); /// // draw something to the pixels here /// # pixels.set(2, 5, true); /// @@ -121,7 +121,7 @@ pub enum Command { /// /// connection.send(command).expect("send failed"); /// ``` - BitmapLinearWin(Origin, PixelGrid, CompressionCode), + BitmapLinearWin(Origin, Bitmap, CompressionCode), /// Set the brightness of all tiles to the same value. /// @@ -337,7 +337,7 @@ impl Command { Ok(Command::BitmapLinearWin( Origin::new(tiles_x as usize * TILE_SIZE, pixels_y as usize), - PixelGrid::load( + Bitmap::load( tile_w as usize * TILE_SIZE, pixel_h as usize, &payload, @@ -371,7 +371,7 @@ impl Command { } } - /// Helper method for Packets into `BitMapLinear*`-Commands + /// Helper method for Packets into `BitmapLinear*`-Commands fn packet_into_linear_bitmap( packet: Packet, ) -> Result<(SpBitVec, CompressionCode), TryFromPacketError> { @@ -496,7 +496,7 @@ mod tests { origin::Pixels, packet::{Header, Packet}, Brightness, BrightnessGrid, Command, CompressionCode, Origin, - PixelGrid, PrimitiveGrid, + Bitmap, PrimitiveGrid, }; fn round_trip(original: Command) { @@ -589,7 +589,7 @@ mod tests { )); round_trip(Command::BitmapLinearWin( Origin::new(0, 0), - PixelGrid::max_sized(), + Bitmap::max_sized(), compression, )); } @@ -714,7 +714,7 @@ mod tests { for compression in all_compressions().to_owned() { let p: Packet = Command::BitmapLinearWin( Origin::new(16, 8), - PixelGrid::new(8, 8), + Bitmap::new(8, 8), compression, ) .into(); diff --git a/crates/servicepoint/src/compression_code.rs b/crates/servicepoint/src/compression_code.rs index 0440c4e..25b0daf 100644 --- a/crates/servicepoint/src/compression_code.rs +++ b/crates/servicepoint/src/compression_code.rs @@ -3,13 +3,13 @@ /// # Examples /// /// ```rust -/// # use servicepoint::{Command, CompressionCode, Origin, PixelGrid}; +/// # use servicepoint::{Command, CompressionCode, Origin, Bitmap}; /// // create command without payload compression -/// # let pixels = PixelGrid::max_sized(); +/// # let pixels = Bitmap::max_sized(); /// _ = Command::BitmapLinearWin(Origin::new(0, 0), pixels, CompressionCode::Uncompressed); /// /// // create command with payload compressed with lzma and appropriate header flags -/// # let pixels = PixelGrid::max_sized(); +/// # let pixels = Bitmap::max_sized(); /// _ = Command::BitmapLinearWin(Origin::new(0, 0), pixels, CompressionCode::Lzma); /// ``` #[repr(u16)] diff --git a/crates/servicepoint/src/lib.rs b/crates/servicepoint/src/lib.rs index d644bba..0d8e871 100644 --- a/crates/servicepoint/src/lib.rs +++ b/crates/servicepoint/src/lib.rs @@ -7,7 +7,7 @@ //! # Examples //! //! ```rust -//! use servicepoint::{Command, CompressionCode, Grid, PixelGrid}; +//! use servicepoint::{Command, CompressionCode, Grid, Bitmap}; //! //! let connection = servicepoint::Connection::open("127.0.0.1:2342") //! .expect("connection failed"); @@ -18,10 +18,10 @@ //! ``` //! //! ```rust -//! # use servicepoint::{Command, CompressionCode, Grid, PixelGrid}; +//! # use servicepoint::{Command, CompressionCode, Grid, Bitmap}; //! # let connection = servicepoint::Connection::open("127.0.0.1:2342").expect("connection failed"); //! // turn on all pixels in a grid -//! let mut pixels = PixelGrid::max_sized(); +//! let mut pixels = Bitmap::max_sized(); //! pixels.fill(true); //! //! // create command to send pixels @@ -48,7 +48,7 @@ pub use crate::cp437::{CharGrid, Cp437Grid}; pub use crate::data_ref::DataRef; pub use crate::grid::Grid; pub use crate::origin::{Origin, Pixels, Tiles}; -pub use crate::pixel_grid::PixelGrid; +pub use crate::bitmap::Bitmap; pub use crate::primitive_grid::PrimitiveGrid; type SpBitVec = BitVec; @@ -64,7 +64,7 @@ mod data_ref; mod grid; mod origin; pub mod packet; -mod pixel_grid; +mod bitmap; mod primitive_grid; /// size of a single tile in one dimension @@ -95,8 +95,8 @@ pub const TILE_HEIGHT: usize = 20; /// # Examples /// /// ```rust -/// # use servicepoint::{PIXEL_HEIGHT, PIXEL_WIDTH, PixelGrid}; -/// let grid = PixelGrid::new(PIXEL_WIDTH, PIXEL_HEIGHT); +/// # use servicepoint::{PIXEL_HEIGHT, PIXEL_WIDTH, Bitmap}; +/// let grid = Bitmap::new(PIXEL_WIDTH, PIXEL_HEIGHT); /// ``` pub const PIXEL_WIDTH: usize = TILE_WIDTH * TILE_SIZE; @@ -105,8 +105,8 @@ pub const PIXEL_WIDTH: usize = TILE_WIDTH * TILE_SIZE; /// # Examples /// /// ```rust -/// # use servicepoint::{PIXEL_HEIGHT, PIXEL_WIDTH, PixelGrid}; -/// let grid = PixelGrid::new(PIXEL_WIDTH, PIXEL_HEIGHT); +/// # use servicepoint::{PIXEL_HEIGHT, PIXEL_WIDTH, Bitmap}; +/// let grid = Bitmap::new(PIXEL_WIDTH, PIXEL_HEIGHT); /// ``` pub const PIXEL_HEIGHT: usize = TILE_HEIGHT * TILE_SIZE; @@ -119,10 +119,10 @@ pub const PIXEL_COUNT: usize = PIXEL_WIDTH * PIXEL_HEIGHT; /// /// ```rust /// # use std::time::Instant; -/// # use servicepoint::{Command, CompressionCode, FRAME_PACING, Origin, PixelGrid}; +/// # use servicepoint::{Command, CompressionCode, FRAME_PACING, Origin, Bitmap}; /// # let connection = servicepoint::Connection::open("172.23.42.29:2342") /// # .expect("connection failed"); -/// # let pixels = PixelGrid::max_sized(); +/// # let pixels = Bitmap::max_sized(); /// loop { /// let start = Instant::now(); /// diff --git a/crates/servicepoint/src/packet.rs b/crates/servicepoint/src/packet.rs index e53a7a1..87fd8b6 100644 --- a/crates/servicepoint/src/packet.rs +++ b/crates/servicepoint/src/packet.rs @@ -28,7 +28,7 @@ use std::mem::size_of; use crate::compression::into_compressed; use crate::{ command_code::CommandCode, Command, CompressionCode, Grid, Offset, Origin, - PixelGrid, Pixels, Tiles, TILE_SIZE, + Bitmap, Pixels, Tiles, TILE_SIZE, }; /// A raw header. @@ -214,7 +214,7 @@ impl From for Packet { } impl Packet { - /// Helper method for `BitMapLinear*`-Commands into [Packet] + /// Helper method for `BitmapLinear*`-Commands into [Packet] #[allow(clippy::cast_possible_truncation)] fn bitmap_linear_into_packet( command: CommandCode, @@ -239,7 +239,7 @@ impl Packet { #[allow(clippy::cast_possible_truncation)] fn bitmap_win_into_packet( origin: Origin, - pixels: PixelGrid, + pixels: Bitmap, compression: CompressionCode, ) -> Packet { debug_assert_eq!(origin.x % 8, 0); diff --git a/crates/servicepoint_binding_c/README.md b/crates/servicepoint_binding_c/README.md index 16240a9..86d38da 100644 --- a/crates/servicepoint_binding_c/README.md +++ b/crates/servicepoint_binding_c/README.md @@ -21,8 +21,8 @@ int main(void) { if (connection == NULL) return 1; - SPPixelGrid *pixels = sp_pixel_grid_new(SP_PIXEL_WIDTH, SP_PIXEL_HEIGHT); - sp_pixel_grid_fill(pixels, true); + SPBitmap *pixels = sp_bitmap_new(SP_PIXEL_WIDTH, SP_PIXEL_HEIGHT); + sp_bitmap_fill(pixels, true); SPCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, Uncompressed); while (sp_connection_send_command(connection, sp_command_clone(command))); diff --git a/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h b/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h index 2f9cab7..b0a420b 100644 --- a/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h +++ b/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h @@ -83,6 +83,20 @@ typedef uint16_t SPCompressionCode; */ typedef struct SPBitVec SPBitVec; +/** + * A grid of pixels. + * + * # Examples + * + * ```C + * Cp437Grid grid = sp_bitmap_new(8, 3); + * sp_bitmap_fill(grid, true); + * sp_bitmap_set(grid, 0, 0, false); + * sp_bitmap_free(grid); + * ``` + */ +typedef struct SPBitmap SPBitmap; + /** * A grid containing brightness values. * @@ -152,20 +166,6 @@ typedef struct SPCp437Grid SPCp437Grid; */ typedef struct SPPacket SPPacket; -/** - * A grid of pixels. - * - * # Examples - * - * ```C - * Cp437Grid grid = sp_pixel_grid_new(8, 3); - * sp_pixel_grid_fill(grid, true); - * sp_pixel_grid_set(grid, 0, 0, false); - * sp_pixel_grid_free(grid); - * ``` - */ -typedef struct SPPixelGrid SPPixelGrid; - /** * Represents a span of memory (`&mut [u8]` ) as a struct usable by C code. * @@ -403,6 +403,219 @@ void sp_bit_vec_set(struct SPBitVec *bit_vec, size_t index, bool value); */ struct SPByteSlice sp_bit_vec_unsafe_data_ref(struct SPBitVec *bit_vec); +/** + * Clones a [SPBitmap]. + * + * Will never return NULL. + * + * # Panics + * + * - when `bitmap` is NULL + * + * # Safety + * + * The caller has to make sure that: + * + * - `bitmap` points to a valid [SPBitmap] + * - `bitmap` is not written to concurrently + * - the returned instance is freed in some way, either by using a consuming function or + * by explicitly calling `sp_bitmap_free`. + */ +struct SPBitmap *sp_bitmap_clone(const struct SPBitmap *bitmap); + +/** + * Sets the state of all pixels in the [SPBitmap]. + * + * # Arguments + * + * - `bitmap`: instance to write to + * - `value`: the value to set all pixels to + * + * # Panics + * + * - when `bitmap` is NULL + * + * # Safety + * + * The caller has to make sure that: + * + * - `bitmap` points to a valid [SPBitmap] + * - `bitmap` is not written to or read from concurrently + */ +void sp_bitmap_fill(struct SPBitmap *bitmap, bool value); + +/** + * Deallocates a [SPBitmap]. + * + * # Panics + * + * - when `bitmap` is NULL + * + * # Safety + * + * The caller has to make sure that: + * + * - `bitmap` points to a valid [SPBitmap] + * - `bitmap` is not used concurrently or after bitmap call + * - `bitmap` was not passed to another consuming function, e.g. to create a [SPCommand] + */ +void sp_bitmap_free(struct SPBitmap *bitmap); + +/** + * Gets the current value at the specified position in the [SPBitmap]. + * + * # Arguments + * + * - `bitmap`: instance to read from + * - `x` and `y`: position of the cell to read + * + * # Panics + * + * - when `bitmap` is NULL + * - when accessing `x` or `y` out of bounds + * + * # Safety + * + * The caller has to make sure that: + * + * - `bitmap` points to a valid [SPBitmap] + * - `bitmap` is not written to concurrently + */ +bool sp_bitmap_get(const struct SPBitmap *bitmap, size_t x, size_t y); + +/** + * Gets the height in pixels of the [SPBitmap] instance. + * + * # Arguments + * + * - `bitmap`: instance to read from + * + * # Panics + * + * - when `bitmap` is NULL + * + * # Safety + * + * The caller has to make sure that: + * + * - `bitmap` points to a valid [SPBitmap] + */ +size_t sp_bitmap_height(const struct SPBitmap *bitmap); + +/** + * Loads a [SPBitmap] with the specified dimensions from the provided data. + * + * # Arguments + * + * - `width`: size in pixels in x-direction + * - `height`: size in pixels in y-direction + * + * returns: [SPBitmap] that contains a copy of the provided data. Will never return NULL. + * + * # Panics + * + * - when `data` is NULL + * - when the dimensions and data size do not match exactly. + * - when the width is not dividable by 8 + * + * # 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_bitmap_free`. + */ +struct SPBitmap *sp_bitmap_load(size_t width, + size_t height, + const uint8_t *data, + size_t data_length); + +/** + * Creates a new [SPBitmap] with the specified dimensions. + * + * # Arguments + * + * - `width`: size in pixels in x-direction + * - `height`: size in pixels in y-direction + * + * returns: [SPBitmap] initialized to all pixels off. Will never return NULL. + * + * # Panics + * + * - when the width is not dividable by 8 + * + * # 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_bitmap_free`. + */ +struct SPBitmap *sp_bitmap_new(size_t width, + size_t height); + +/** + * Sets the value of the specified position in the [SPBitmap]. + * + * # Arguments + * + * - `bitmap`: 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 `bitmap` is NULL + * - when accessing `x` or `y` out of bounds + * + * # Safety + * + * The caller has to make sure that: + * + * - `bitmap` points to a valid [SPBitmap] + * - `bitmap` is not written to or read from concurrently + */ +void sp_bitmap_set(struct SPBitmap *bitmap, size_t x, size_t y, bool value); + +/** + * Gets an unsafe reference to the data of the [SPBitmap] instance. + * + * # Panics + * + * - when `bitmap` is NULL + * + * # Safety + * + * The caller has to make sure that: + * + * - `bitmap` points to a valid [SPBitmap] + * - the returned memory range is never accessed after the passed [SPBitmap] has been freed + * - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly + */ +struct SPByteSlice sp_bitmap_unsafe_data_ref(struct SPBitmap *bitmap); + +/** + * Gets the width in pixels of the [SPBitmap] instance. + * + * # Arguments + * + * - `bitmap`: instance to read from + * + * # Panics + * + * - when `bitmap` is NULL + * + * # Safety + * + * The caller has to make sure that: + * + * - `bitmap` points to a valid [SPBitmap] + */ +size_t sp_bitmap_width(const struct SPBitmap *bitmap); + /** * Clones a [SPBrightnessGrid]. * @@ -726,28 +939,28 @@ struct SPCommand *sp_command_bitmap_linear_or(size_t offset, /** * Sets a window of pixels to the specified values. * - * The passed [SPPixelGrid] gets consumed. + * The passed [SPBitmap] gets consumed. * * Returns: a new [Command::BitmapLinearWin] instance. Will never return NULL. * * # Panics * - * - when `pixel_grid` is null + * - when `bitmap` is null * - when `compression_code` is not a valid value * * # Safety * * The caller has to make sure that: * - * - `pixel_grid` points to a valid instance of [SPPixelGrid] - * - `pixel_grid` is not used concurrently or after this call + * - `bitmap` points to a valid instance of [SPBitmap] + * - `bitmap` is not used concurrently or after this call * - `compression` matches one of the allowed enum values * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_command_free`. */ struct SPCommand *sp_command_bitmap_linear_win(size_t x, size_t y, - struct SPPixelGrid *pixel_grid, + struct SPBitmap *bitmap, SPCompressionCode compression_code); /** @@ -1330,224 +1543,6 @@ struct SPPacket *sp_packet_from_command(struct SPCommand *command); struct SPPacket *sp_packet_try_load(const uint8_t *data, size_t length); -/** - * Clones a [SPPixelGrid]. - * - * Will never return NULL. - * - * # Panics - * - * - when `pixel_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `pixel_grid` points to a valid [SPPixelGrid] - * - `pixel_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_pixel_grid_free`. - */ -struct SPPixelGrid *sp_pixel_grid_clone(const struct SPPixelGrid *pixel_grid); - -/** - * Sets the state of all pixels in the [SPPixelGrid]. - * - * # Arguments - * - * - `pixel_grid`: instance to write to - * - `value`: the value to set all pixels to - * - * # Panics - * - * - when `pixel_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `pixel_grid` points to a valid [SPPixelGrid] - * - `pixel_grid` is not written to or read from concurrently - */ -void sp_pixel_grid_fill(struct SPPixelGrid *pixel_grid, bool value); - -/** - * Deallocates a [SPPixelGrid]. - * - * # Panics - * - * - when `pixel_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `pixel_grid` points to a valid [SPPixelGrid] - * - `pixel_grid` is not used concurrently or after pixel_grid call - * - `pixel_grid` was not passed to another consuming function, e.g. to create a [SPCommand] - */ -void sp_pixel_grid_free(struct SPPixelGrid *pixel_grid); - -/** - * Gets the current value at the specified position in the [SPPixelGrid]. - * - * # Arguments - * - * - `pixel_grid`: instance to read from - * - `x` and `y`: position of the cell to read - * - * # Panics - * - * - when `pixel_grid` is NULL - * - when accessing `x` or `y` out of bounds - * - * # Safety - * - * The caller has to make sure that: - * - * - `pixel_grid` points to a valid [SPPixelGrid] - * - `pixel_grid` is not written to concurrently - */ -bool sp_pixel_grid_get(const struct SPPixelGrid *pixel_grid, - size_t x, - size_t y); - -/** - * Gets the height in pixels of the [SPPixelGrid] instance. - * - * # Arguments - * - * - `pixel_grid`: instance to read from - * - * # Panics - * - * - when `pixel_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `pixel_grid` points to a valid [SPPixelGrid] - */ -size_t sp_pixel_grid_height(const struct SPPixelGrid *pixel_grid); - -/** - * Loads a [SPPixelGrid] with the specified dimensions from the provided data. - * - * # Arguments - * - * - `width`: size in pixels in x-direction - * - `height`: size in pixels in y-direction - * - * returns: [SPPixelGrid] that contains a copy of the provided data. Will never return NULL. - * - * # Panics - * - * - when `data` is NULL - * - when the dimensions and data size do not match exactly. - * - when the width is not dividable by 8 - * - * # 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_pixel_grid_free`. - */ -struct SPPixelGrid *sp_pixel_grid_load(size_t width, - size_t height, - const uint8_t *data, - size_t data_length); - -/** - * Creates a new [SPPixelGrid] with the specified dimensions. - * - * # Arguments - * - * - `width`: size in pixels in x-direction - * - `height`: size in pixels in y-direction - * - * returns: [SPPixelGrid] initialized to all pixels off. Will never return NULL. - * - * # Panics - * - * - when the width is not dividable by 8 - * - * # 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_pixel_grid_free`. - */ -struct SPPixelGrid *sp_pixel_grid_new(size_t width, - size_t height); - -/** - * Sets the value of the specified position in the [SPPixelGrid]. - * - * # Arguments - * - * - `pixel_grid`: 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 `pixel_grid` is NULL - * - when accessing `x` or `y` out of bounds - * - * # Safety - * - * The caller has to make sure that: - * - * - `pixel_grid` points to a valid [SPPixelGrid] - * - `pixel_grid` is not written to or read from concurrently - */ -void sp_pixel_grid_set(struct SPPixelGrid *pixel_grid, - size_t x, - size_t y, - bool value); - -/** - * Gets an unsafe reference to the data of the [SPPixelGrid] instance. - * - * # Panics - * - * - when `pixel_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `pixel_grid` points to a valid [SPPixelGrid] - * - the returned memory range is never accessed after the passed [SPPixelGrid] has been freed - * - the returned memory range is never accessed concurrently, either via the [SPPixelGrid] or directly - */ -struct SPByteSlice sp_pixel_grid_unsafe_data_ref(struct SPPixelGrid *pixel_grid); - -/** - * Gets the width in pixels of the [SPPixelGrid] instance. - * - * # Arguments - * - * - `pixel_grid`: instance to read from - * - * # Panics - * - * - when `pixel_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `pixel_grid` points to a valid [SPPixelGrid] - */ -size_t sp_pixel_grid_width(const struct SPPixelGrid *pixel_grid); - #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/crates/servicepoint_binding_c/examples/lang_c/src/main.c b/crates/servicepoint_binding_c/examples/lang_c/src/main.c index 6c23ab0..e84e510 100644 --- a/crates/servicepoint_binding_c/examples/lang_c/src/main.c +++ b/crates/servicepoint_binding_c/examples/lang_c/src/main.c @@ -6,8 +6,8 @@ int main(void) { if (connection == NULL) return 1; - SPPixelGrid *pixels = sp_pixel_grid_new(SP_PIXEL_WIDTH, SP_PIXEL_HEIGHT); - sp_pixel_grid_fill(pixels, true); + SPBitmap *pixels = sp_bitmap_new(SP_PIXEL_WIDTH, SP_PIXEL_HEIGHT); + sp_bitmap_fill(pixels, true); SPCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, SP_COMPRESSION_CODE_UNCOMPRESSED); while (sp_connection_send_command(connection, sp_command_clone(command))); diff --git a/crates/servicepoint_binding_c/src/bitmap.rs b/crates/servicepoint_binding_c/src/bitmap.rs new file mode 100644 index 0000000..22d9a57 --- /dev/null +++ b/crates/servicepoint_binding_c/src/bitmap.rs @@ -0,0 +1,290 @@ +//! C functions for interacting with [SPBitmap]s +//! +//! prefix `sp_bitmap_` + +use servicepoint::{DataRef, Grid}; + +use crate::byte_slice::SPByteSlice; + +/// A grid of pixels. +/// +/// # Examples +/// +/// ```C +/// Cp437Grid grid = sp_bitmap_new(8, 3); +/// sp_bitmap_fill(grid, true); +/// sp_bitmap_set(grid, 0, 0, false); +/// sp_bitmap_free(grid); +/// ``` +pub struct SPBitmap(pub(crate) servicepoint::Bitmap); + +/// Creates a new [SPBitmap] with the specified dimensions. +/// +/// # Arguments +/// +/// - `width`: size in pixels in x-direction +/// - `height`: size in pixels in y-direction +/// +/// returns: [SPBitmap] initialized to all pixels off. Will never return NULL. +/// +/// # Panics +/// +/// - when the width is not dividable by 8 +/// +/// # 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_bitmap_free`. +#[no_mangle] +pub unsafe extern "C" fn sp_bitmap_new( + width: usize, + height: usize, +) -> *mut SPBitmap { + let result = Box::into_raw(Box::new(SPBitmap(servicepoint::Bitmap::new( + width, height, + )))); + assert!(!result.is_null()); + result +} + +/// Loads a [SPBitmap] with the specified dimensions from the provided data. +/// +/// # Arguments +/// +/// - `width`: size in pixels in x-direction +/// - `height`: size in pixels in y-direction +/// +/// returns: [SPBitmap] that contains a copy of the provided data. Will never return NULL. +/// +/// # Panics +/// +/// - when `data` is NULL +/// - when the dimensions and data size do not match exactly. +/// - when the width is not dividable by 8 +/// +/// # 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_bitmap_free`. +#[no_mangle] +pub unsafe extern "C" fn sp_bitmap_load( + width: usize, + height: usize, + data: *const u8, + data_length: usize, +) -> *mut SPBitmap { + assert!(!data.is_null()); + let data = std::slice::from_raw_parts(data, data_length); + let result = Box::into_raw(Box::new(SPBitmap(servicepoint::Bitmap::load( + width, height, data, + )))); + assert!(!result.is_null()); + result +} + +/// Clones a [SPBitmap]. +/// +/// Will never return NULL. +/// +/// # Panics +/// +/// - when `bitmap` is NULL +/// +/// # Safety +/// +/// The caller has to make sure that: +/// +/// - `bitmap` points to a valid [SPBitmap] +/// - `bitmap` is not written to concurrently +/// - 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_clone( + bitmap: *const SPBitmap, +) -> *mut SPBitmap { + assert!(!bitmap.is_null()); + let result = Box::into_raw(Box::new(SPBitmap((*bitmap).0.clone()))); + assert!(!result.is_null()); + result +} + +/// Deallocates a [SPBitmap]. +/// +/// # Panics +/// +/// - when `bitmap` is NULL +/// +/// # Safety +/// +/// The caller has to make sure that: +/// +/// - `bitmap` points to a valid [SPBitmap] +/// - `bitmap` is not used concurrently or after bitmap call +/// - `bitmap` was not passed to another consuming function, e.g. to create a [SPCommand] +#[no_mangle] +pub unsafe extern "C" fn sp_bitmap_free(bitmap: *mut SPBitmap) { + assert!(!bitmap.is_null()); + _ = Box::from_raw(bitmap); +} + +/// Gets the current value at the specified position in the [SPBitmap]. +/// +/// # Arguments +/// +/// - `bitmap`: instance to read from +/// - `x` and `y`: position of the cell to read +/// +/// # Panics +/// +/// - when `bitmap` is NULL +/// - when accessing `x` or `y` out of bounds +/// +/// # Safety +/// +/// The caller has to make sure that: +/// +/// - `bitmap` points to a valid [SPBitmap] +/// - `bitmap` is not written to concurrently +#[no_mangle] +pub unsafe extern "C" fn sp_bitmap_get( + bitmap: *const SPBitmap, + x: usize, + y: usize, +) -> bool { + assert!(!bitmap.is_null()); + (*bitmap).0.get(x, y) +} + +/// Sets the value of the specified position in the [SPBitmap]. +/// +/// # Arguments +/// +/// - `bitmap`: 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 `bitmap` is NULL +/// - when accessing `x` or `y` out of bounds +/// +/// # Safety +/// +/// The caller has to make sure that: +/// +/// - `bitmap` points to a valid [SPBitmap] +/// - `bitmap` is not written to or read from concurrently +#[no_mangle] +pub unsafe extern "C" fn sp_bitmap_set( + bitmap: *mut SPBitmap, + x: usize, + y: usize, + value: bool, +) { + assert!(!bitmap.is_null()); + (*bitmap).0.set(x, y, value); +} + +/// Sets the state of all pixels in the [SPBitmap]. +/// +/// # Arguments +/// +/// - `bitmap`: instance to write to +/// - `value`: the value to set all pixels to +/// +/// # Panics +/// +/// - when `bitmap` is NULL +/// +/// # Safety +/// +/// The caller has to make sure that: +/// +/// - `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 SPBitmap, + value: bool, +) { + assert!(!bitmap.is_null()); + (*bitmap).0.fill(value); +} + +/// Gets the width in pixels of the [SPBitmap] instance. +/// +/// # Arguments +/// +/// - `bitmap`: instance to read from +/// +/// # Panics +/// +/// - when `bitmap` is NULL +/// +/// # Safety +/// +/// The caller has to make sure that: +/// +/// - `bitmap` points to a valid [SPBitmap] +#[no_mangle] +pub unsafe extern "C" fn sp_bitmap_width( + bitmap: *const SPBitmap, +) -> usize { + assert!(!bitmap.is_null()); + (*bitmap).0.width() +} + +/// Gets the height in pixels of the [SPBitmap] instance. +/// +/// # Arguments +/// +/// - `bitmap`: instance to read from +/// +/// # Panics +/// +/// - when `bitmap` is NULL +/// +/// # Safety +/// +/// The caller has to make sure that: +/// +/// - `bitmap` points to a valid [SPBitmap] +#[no_mangle] +pub unsafe extern "C" fn sp_bitmap_height( + bitmap: *const SPBitmap, +) -> usize { + assert!(!bitmap.is_null()); + (*bitmap).0.height() +} + +/// Gets an unsafe reference to the data of the [SPBitmap] instance. +/// +/// # Panics +/// +/// - when `bitmap` is NULL +/// +/// # Safety +/// +/// The caller has to make sure that: +/// +/// - `bitmap` points to a valid [SPBitmap] +/// - the returned memory range is never accessed after the passed [SPBitmap] has been freed +/// - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly +#[no_mangle] +pub unsafe extern "C" fn sp_bitmap_unsafe_data_ref( + bitmap: *mut SPBitmap, +) -> SPByteSlice { + assert!(!bitmap.is_null()); + let data = (*bitmap).0.data_ref_mut(); + SPByteSlice { + start: data.as_mut_ptr_range().start, + length: data.len(), + } +} diff --git a/crates/servicepoint_binding_c/src/command.rs b/crates/servicepoint_binding_c/src/command.rs index 4bbc408..4a64829 100644 --- a/crates/servicepoint_binding_c/src/command.rs +++ b/crates/servicepoint_binding_c/src/command.rs @@ -8,7 +8,7 @@ use servicepoint::{Brightness, Origin}; use crate::{ SPBitVec, SPBrightnessGrid, SPCompressionCode, SPCp437Grid, SPPacket, - SPPixelGrid, + SPBitmap, }; /// A low-level display command. @@ -413,21 +413,21 @@ pub unsafe extern "C" fn sp_command_cp437_data( /// Sets a window of pixels to the specified values. /// -/// The passed [SPPixelGrid] gets consumed. +/// The passed [SPBitmap] gets consumed. /// /// Returns: a new [Command::BitmapLinearWin] instance. Will never return NULL. /// /// # Panics /// -/// - when `pixel_grid` is null +/// - when `bitmap` is null /// - when `compression_code` is not a valid value /// /// # Safety /// /// The caller has to make sure that: /// -/// - `pixel_grid` points to a valid instance of [SPPixelGrid] -/// - `pixel_grid` is not used concurrently or after this call +/// - `bitmap` points to a valid instance of [SPBitmap] +/// - `bitmap` is not used concurrently or after this call /// - `compression` matches one of the allowed enum values /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or /// by explicitly calling `sp_command_free`. @@ -435,11 +435,11 @@ pub unsafe extern "C" fn sp_command_cp437_data( pub unsafe extern "C" fn sp_command_bitmap_linear_win( x: usize, y: usize, - pixel_grid: *mut SPPixelGrid, + bitmap: *mut SPBitmap, compression_code: SPCompressionCode, ) -> *mut SPCommand { - assert!(!pixel_grid.is_null()); - let byte_grid = (*Box::from_raw(pixel_grid)).0; + assert!(!bitmap.is_null()); + let byte_grid = (*Box::from_raw(bitmap)).0; let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinearWin( Origin::new(x, y), byte_grid, diff --git a/crates/servicepoint_binding_c/src/lib.rs b/crates/servicepoint_binding_c/src/lib.rs index d6f839b..7698252 100644 --- a/crates/servicepoint_binding_c/src/lib.rs +++ b/crates/servicepoint_binding_c/src/lib.rs @@ -13,8 +13,8 @@ //! if (connection == NULL) //! return 1; //! -//! SPPixelGrid *pixels = sp_pixel_grid_new(SP_PIXEL_WIDTH, SP_PIXEL_HEIGHT); -//! sp_pixel_grid_fill(pixels, true); +//! SPBitmap *pixels = sp_bitmap_new(SP_PIXEL_WIDTH, SP_PIXEL_HEIGHT); +//! sp_bitmap_fill(pixels, true); //! //! SPCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, Uncompressed); //! while (sp_connection_send_command(connection, sp_command_clone(command))); @@ -33,7 +33,7 @@ pub use crate::connection::*; pub use crate::constants::*; pub use crate::cp437_grid::*; pub use crate::packet::*; -pub use crate::pixel_grid::*; +pub use crate::bitmap::*; mod bit_vec; mod brightness_grid; @@ -43,4 +43,4 @@ mod connection; mod constants; mod cp437_grid; mod packet; -mod pixel_grid; +mod bitmap; diff --git a/crates/servicepoint_binding_c/src/pixel_grid.rs b/crates/servicepoint_binding_c/src/pixel_grid.rs deleted file mode 100644 index 8e937fc..0000000 --- a/crates/servicepoint_binding_c/src/pixel_grid.rs +++ /dev/null @@ -1,290 +0,0 @@ -//! C functions for interacting with [SPPixelGrid]s -//! -//! prefix `sp_pixel_grid_` - -use servicepoint::{DataRef, Grid}; - -use crate::byte_slice::SPByteSlice; - -/// A grid of pixels. -/// -/// # Examples -/// -/// ```C -/// Cp437Grid grid = sp_pixel_grid_new(8, 3); -/// sp_pixel_grid_fill(grid, true); -/// sp_pixel_grid_set(grid, 0, 0, false); -/// sp_pixel_grid_free(grid); -/// ``` -pub struct SPPixelGrid(pub(crate) servicepoint::PixelGrid); - -/// Creates a new [SPPixelGrid] with the specified dimensions. -/// -/// # Arguments -/// -/// - `width`: size in pixels in x-direction -/// - `height`: size in pixels in y-direction -/// -/// returns: [SPPixelGrid] initialized to all pixels off. Will never return NULL. -/// -/// # Panics -/// -/// - when the width is not dividable by 8 -/// -/// # 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_pixel_grid_free`. -#[no_mangle] -pub unsafe extern "C" fn sp_pixel_grid_new( - width: usize, - height: usize, -) -> *mut SPPixelGrid { - let result = Box::into_raw(Box::new(SPPixelGrid(servicepoint::PixelGrid::new( - width, height, - )))); - assert!(!result.is_null()); - result -} - -/// Loads a [SPPixelGrid] with the specified dimensions from the provided data. -/// -/// # Arguments -/// -/// - `width`: size in pixels in x-direction -/// - `height`: size in pixels in y-direction -/// -/// returns: [SPPixelGrid] that contains a copy of the provided data. Will never return NULL. -/// -/// # Panics -/// -/// - when `data` is NULL -/// - when the dimensions and data size do not match exactly. -/// - when the width is not dividable by 8 -/// -/// # 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_pixel_grid_free`. -#[no_mangle] -pub unsafe extern "C" fn sp_pixel_grid_load( - width: usize, - height: usize, - data: *const u8, - data_length: usize, -) -> *mut SPPixelGrid { - assert!(!data.is_null()); - let data = std::slice::from_raw_parts(data, data_length); - let result = Box::into_raw(Box::new(SPPixelGrid(servicepoint::PixelGrid::load( - width, height, data, - )))); - assert!(!result.is_null()); - result -} - -/// Clones a [SPPixelGrid]. -/// -/// Will never return NULL. -/// -/// # Panics -/// -/// - when `pixel_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `pixel_grid` points to a valid [SPPixelGrid] -/// - `pixel_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_pixel_grid_free`. -#[no_mangle] -pub unsafe extern "C" fn sp_pixel_grid_clone( - pixel_grid: *const SPPixelGrid, -) -> *mut SPPixelGrid { - assert!(!pixel_grid.is_null()); - let result = Box::into_raw(Box::new(SPPixelGrid((*pixel_grid).0.clone()))); - assert!(!result.is_null()); - result -} - -/// Deallocates a [SPPixelGrid]. -/// -/// # Panics -/// -/// - when `pixel_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `pixel_grid` points to a valid [SPPixelGrid] -/// - `pixel_grid` is not used concurrently or after pixel_grid call -/// - `pixel_grid` was not passed to another consuming function, e.g. to create a [SPCommand] -#[no_mangle] -pub unsafe extern "C" fn sp_pixel_grid_free(pixel_grid: *mut SPPixelGrid) { - assert!(!pixel_grid.is_null()); - _ = Box::from_raw(pixel_grid); -} - -/// Gets the current value at the specified position in the [SPPixelGrid]. -/// -/// # Arguments -/// -/// - `pixel_grid`: instance to read from -/// - `x` and `y`: position of the cell to read -/// -/// # Panics -/// -/// - when `pixel_grid` is NULL -/// - when accessing `x` or `y` out of bounds -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `pixel_grid` points to a valid [SPPixelGrid] -/// - `pixel_grid` is not written to concurrently -#[no_mangle] -pub unsafe extern "C" fn sp_pixel_grid_get( - pixel_grid: *const SPPixelGrid, - x: usize, - y: usize, -) -> bool { - assert!(!pixel_grid.is_null()); - (*pixel_grid).0.get(x, y) -} - -/// Sets the value of the specified position in the [SPPixelGrid]. -/// -/// # Arguments -/// -/// - `pixel_grid`: 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 `pixel_grid` is NULL -/// - when accessing `x` or `y` out of bounds -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `pixel_grid` points to a valid [SPPixelGrid] -/// - `pixel_grid` is not written to or read from concurrently -#[no_mangle] -pub unsafe extern "C" fn sp_pixel_grid_set( - pixel_grid: *mut SPPixelGrid, - x: usize, - y: usize, - value: bool, -) { - assert!(!pixel_grid.is_null()); - (*pixel_grid).0.set(x, y, value); -} - -/// Sets the state of all pixels in the [SPPixelGrid]. -/// -/// # Arguments -/// -/// - `pixel_grid`: instance to write to -/// - `value`: the value to set all pixels to -/// -/// # Panics -/// -/// - when `pixel_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `pixel_grid` points to a valid [SPPixelGrid] -/// - `pixel_grid` is not written to or read from concurrently -#[no_mangle] -pub unsafe extern "C" fn sp_pixel_grid_fill( - pixel_grid: *mut SPPixelGrid, - value: bool, -) { - assert!(!pixel_grid.is_null()); - (*pixel_grid).0.fill(value); -} - -/// Gets the width in pixels of the [SPPixelGrid] instance. -/// -/// # Arguments -/// -/// - `pixel_grid`: instance to read from -/// -/// # Panics -/// -/// - when `pixel_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `pixel_grid` points to a valid [SPPixelGrid] -#[no_mangle] -pub unsafe extern "C" fn sp_pixel_grid_width( - pixel_grid: *const SPPixelGrid, -) -> usize { - assert!(!pixel_grid.is_null()); - (*pixel_grid).0.width() -} - -/// Gets the height in pixels of the [SPPixelGrid] instance. -/// -/// # Arguments -/// -/// - `pixel_grid`: instance to read from -/// -/// # Panics -/// -/// - when `pixel_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `pixel_grid` points to a valid [SPPixelGrid] -#[no_mangle] -pub unsafe extern "C" fn sp_pixel_grid_height( - pixel_grid: *const SPPixelGrid, -) -> usize { - assert!(!pixel_grid.is_null()); - (*pixel_grid).0.height() -} - -/// Gets an unsafe reference to the data of the [SPPixelGrid] instance. -/// -/// # Panics -/// -/// - when `pixel_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `pixel_grid` points to a valid [SPPixelGrid] -/// - the returned memory range is never accessed after the passed [SPPixelGrid] has been freed -/// - the returned memory range is never accessed concurrently, either via the [SPPixelGrid] or directly -#[no_mangle] -pub unsafe extern "C" fn sp_pixel_grid_unsafe_data_ref( - pixel_grid: *mut SPPixelGrid, -) -> SPByteSlice { - assert!(!pixel_grid.is_null()); - let data = (*pixel_grid).0.data_ref_mut(); - SPByteSlice { - start: data.as_mut_ptr_range().start, - length: data.len(), - } -} diff --git a/crates/servicepoint_binding_cs/README.md b/crates/servicepoint_binding_cs/README.md index 0f5ee3d..bd2107a 100644 --- a/crates/servicepoint_binding_cs/README.md +++ b/crates/servicepoint_binding_cs/README.md @@ -11,7 +11,7 @@ using ServicePoint; // using statement calls Dispose() on scope exit, which frees unmanaged instances using var connection = Connection.Open("127.0.0.1:2342"); -using var pixels = PixelGrid.New(Constants.PixelWidth, Constants.PixelHeight); +using var pixels = Bitmap.New(Constants.PixelWidth, Constants.PixelHeight); while (true) { diff --git a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs b/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs index 42a5977..df0873f 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs @@ -464,341 +464,6 @@ namespace ServicePoint.BindGen [DllImport(__DllName, EntryPoint = "sp_brightness_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern ByteSlice sp_brightness_grid_unsafe_data_ref(BrightnessGrid* brightness_grid); - /// - /// Tries to turn a [SPPacket] into a [SPCommand]. - /// - /// The packet is deallocated in the process. - /// - /// Returns: pointer to new [SPCommand] instance or NULL if parsing failed. - /// - /// # Panics - /// - /// - when `packet` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - [SPPacket] points to a valid instance of [SPPacket] - /// - [SPPacket] is not used concurrently or after this call - /// - the result is checked for NULL - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_try_from_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_try_from_packet(Packet* packet); - - /// - /// Clones a [SPCommand] instance. - /// - /// returns: new [SPCommand] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `command` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `command` points to a valid instance of [SPCommand] - /// - `command` is not written to concurrently - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_clone(Command* command); - - /// - /// Set all pixels to the off state. - /// - /// Does not affect brightness. - /// - /// Returns: a new [Command::Clear] instance. Will never return NULL. - /// - /// # Examples - /// - /// ```C - /// sp_connection_send_command(connection, sp_command_clear()); - /// ``` - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_clear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_clear(); - - /// - /// Kills the udp daemon on the display, which usually results in a restart. - /// - /// Please do not send this in your normal program flow. - /// - /// Returns: a new [Command::HardReset] instance. Will never return NULL. - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_hard_reset", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_hard_reset(); - - /// - /// A yet-to-be-tested command. - /// - /// Returns: a new `Command::FadeOut` instance. Will never return NULL. - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_fade_out", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_fade_out(); - - /// - /// Set the brightness of all tiles to the same value. - /// - /// Returns: a new [Command::Brightness] instance. Will never return NULL. - /// - /// # Panics - /// - /// - When the provided brightness value is out of range (0-11). - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_brightness(byte brightness); - - /// - /// Set the brightness of individual tiles in a rectangular area of the display. - /// - /// The passed [SPBrightnessGrid] gets consumed. - /// - /// Returns: a new [Command::CharBrightness] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `grid` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `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`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_char_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_char_brightness(nuint x, nuint y, BrightnessGrid* grid); - - /// - /// Set pixel data starting at the pixel offset on screen. - /// - /// The screen will continuously overwrite more pixel data without regarding the offset, meaning - /// once the starting row is full, overwriting will continue on column 0. - /// - /// The contained [SPBitVec] is always uncompressed. - /// - /// The passed [SPBitVec] gets consumed. - /// - /// Returns: a new [Command::BitmapLinear] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `bit_vec` is null - /// - when `compression_code` is not a valid value - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid instance of [SPBitVec] - /// - `bit_vec` is not used concurrently or after this call - /// - `compression` matches one of the allowed enum values - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_bitmap_linear(nuint offset, BitVec* bit_vec, CompressionCode compression); - - /// - /// Set pixel data according to an and-mask starting at the offset. - /// - /// The screen will continuously overwrite more pixel data without regarding the offset, meaning - /// once the starting row is full, overwriting will continue on column 0. - /// - /// The contained [SPBitVec] is always uncompressed. - /// - /// The passed [SPBitVec] gets consumed. - /// - /// Returns: a new [Command::BitmapLinearAnd] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `bit_vec` is null - /// - when `compression_code` is not a valid value - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid instance of [SPBitVec] - /// - `bit_vec` is not used concurrently or after this call - /// - `compression` matches one of the allowed enum values - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_and", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_bitmap_linear_and(nuint offset, BitVec* bit_vec, CompressionCode compression); - - /// - /// Set pixel data according to an or-mask starting at the offset. - /// - /// The screen will continuously overwrite more pixel data without regarding the offset, meaning - /// once the starting row is full, overwriting will continue on column 0. - /// - /// The contained [SPBitVec] is always uncompressed. - /// - /// The passed [SPBitVec] gets consumed. - /// - /// Returns: a new [Command::BitmapLinearOr] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `bit_vec` is null - /// - when `compression_code` is not a valid value - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid instance of [SPBitVec] - /// - `bit_vec` is not used concurrently or after this call - /// - `compression` matches one of the allowed enum values - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_or", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_bitmap_linear_or(nuint offset, BitVec* bit_vec, CompressionCode compression); - - /// - /// Set pixel data according to a xor-mask starting at the offset. - /// - /// The screen will continuously overwrite more pixel data without regarding the offset, meaning - /// once the starting row is full, overwriting will continue on column 0. - /// - /// The contained [SPBitVec] is always uncompressed. - /// - /// The passed [SPBitVec] gets consumed. - /// - /// Returns: a new [Command::BitmapLinearXor] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `bit_vec` is null - /// - when `compression_code` is not a valid value - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid instance of [SPBitVec] - /// - `bit_vec` is not used concurrently or after this call - /// - `compression` matches one of the allowed enum values - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_xor", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_bitmap_linear_xor(nuint offset, BitVec* bit_vec, CompressionCode compression); - - /// - /// Show text on the screen. - /// - /// The passed [SPCp437Grid] gets consumed. - /// - /// Returns: a new [Command::Cp437Data] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `grid` is null - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `grid` points to a valid instance of [SPCp437Grid] - /// - `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`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_cp437_data", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_cp437_data(nuint x, nuint y, Cp437Grid* grid); - - /// - /// Sets a window of pixels to the specified values. - /// - /// The passed [SPPixelGrid] gets consumed. - /// - /// Returns: a new [Command::BitmapLinearWin] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `pixel_grid` is null - /// - when `compression_code` is not a valid value - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `pixel_grid` points to a valid instance of [SPPixelGrid] - /// - `pixel_grid` is not used concurrently or after this call - /// - `compression` matches one of the allowed enum values - /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_command_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_win", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_bitmap_linear_win(nuint x, nuint y, PixelGrid* pixel_grid, CompressionCode compression_code); - - /// - /// Deallocates a [SPCommand]. - /// - /// # Examples - /// - /// ```C - /// SPCommand c = sp_command_clear(); - /// sp_command_free(c); - /// ``` - /// - /// # Panics - /// - /// - when `command` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `command` points to a valid [SPCommand] - /// - `command` is not used concurrently or after this call - /// - `command` was not passed to another consuming function, e.g. to create a [SPPacket] - /// - [DllImport(__DllName, EntryPoint = "sp_command_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_command_free(Command* command); - /// /// Creates a new instance of [SPConnection]. /// @@ -1172,14 +837,349 @@ namespace ServicePoint.BindGen public static extern void sp_packet_free(Packet* packet); /// - /// Creates a new [SPPixelGrid] with the specified dimensions. + /// Tries to turn a [SPPacket] into a [SPCommand]. + /// + /// The packet is deallocated in the process. + /// + /// Returns: pointer to new [SPCommand] instance or NULL if parsing failed. + /// + /// # Panics + /// + /// - when `packet` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - [SPPacket] points to a valid instance of [SPPacket] + /// - [SPPacket] is not used concurrently or after this call + /// - the result is checked for NULL + /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or + /// by explicitly calling `sp_command_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_command_try_from_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_try_from_packet(Packet* packet); + + /// + /// Clones a [SPCommand] instance. + /// + /// returns: new [SPCommand] instance. Will never return NULL. + /// + /// # Panics + /// + /// - when `command` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `command` points to a valid instance of [SPCommand] + /// - `command` is not written to concurrently + /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or + /// by explicitly calling `sp_command_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_command_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_clone(Command* command); + + /// + /// Set all pixels to the off state. + /// + /// Does not affect brightness. + /// + /// Returns: a new [Command::Clear] instance. Will never return NULL. + /// + /// # Examples + /// + /// ```C + /// sp_connection_send_command(connection, sp_command_clear()); + /// ``` + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or + /// by explicitly calling `sp_command_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_command_clear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_clear(); + + /// + /// Kills the udp daemon on the display, which usually results in a restart. + /// + /// Please do not send this in your normal program flow. + /// + /// Returns: a new [Command::HardReset] instance. Will never return NULL. + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or + /// by explicitly calling `sp_command_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_command_hard_reset", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_hard_reset(); + + /// + /// A yet-to-be-tested command. + /// + /// Returns: a new `Command::FadeOut` instance. Will never return NULL. + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or + /// by explicitly calling `sp_command_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_command_fade_out", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_fade_out(); + + /// + /// Set the brightness of all tiles to the same value. + /// + /// Returns: a new [Command::Brightness] instance. Will never return NULL. + /// + /// # Panics + /// + /// - When the provided brightness value is out of range (0-11). + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or + /// by explicitly calling `sp_command_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_command_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_brightness(byte brightness); + + /// + /// Set the brightness of individual tiles in a rectangular area of the display. + /// + /// The passed [SPBrightnessGrid] gets consumed. + /// + /// Returns: a new [Command::CharBrightness] instance. Will never return NULL. + /// + /// # Panics + /// + /// - when `grid` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `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`. + /// + [DllImport(__DllName, EntryPoint = "sp_command_char_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_char_brightness(nuint x, nuint y, BrightnessGrid* grid); + + /// + /// Set pixel data starting at the pixel offset on screen. + /// + /// The screen will continuously overwrite more pixel data without regarding the offset, meaning + /// once the starting row is full, overwriting will continue on column 0. + /// + /// The contained [SPBitVec] is always uncompressed. + /// + /// The passed [SPBitVec] gets consumed. + /// + /// Returns: a new [Command::BitmapLinear] instance. Will never return NULL. + /// + /// # Panics + /// + /// - when `bit_vec` is null + /// - when `compression_code` is not a valid value + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bit_vec` points to a valid instance of [SPBitVec] + /// - `bit_vec` is not used concurrently or after this call + /// - `compression` matches one of the allowed enum values + /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or + /// by explicitly calling `sp_command_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_bitmap_linear(nuint offset, BitVec* bit_vec, CompressionCode compression); + + /// + /// Set pixel data according to an and-mask starting at the offset. + /// + /// The screen will continuously overwrite more pixel data without regarding the offset, meaning + /// once the starting row is full, overwriting will continue on column 0. + /// + /// The contained [SPBitVec] is always uncompressed. + /// + /// The passed [SPBitVec] gets consumed. + /// + /// Returns: a new [Command::BitmapLinearAnd] instance. Will never return NULL. + /// + /// # Panics + /// + /// - when `bit_vec` is null + /// - when `compression_code` is not a valid value + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bit_vec` points to a valid instance of [SPBitVec] + /// - `bit_vec` is not used concurrently or after this call + /// - `compression` matches one of the allowed enum values + /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or + /// by explicitly calling `sp_command_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_and", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_bitmap_linear_and(nuint offset, BitVec* bit_vec, CompressionCode compression); + + /// + /// Set pixel data according to an or-mask starting at the offset. + /// + /// The screen will continuously overwrite more pixel data without regarding the offset, meaning + /// once the starting row is full, overwriting will continue on column 0. + /// + /// The contained [SPBitVec] is always uncompressed. + /// + /// The passed [SPBitVec] gets consumed. + /// + /// Returns: a new [Command::BitmapLinearOr] instance. Will never return NULL. + /// + /// # Panics + /// + /// - when `bit_vec` is null + /// - when `compression_code` is not a valid value + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bit_vec` points to a valid instance of [SPBitVec] + /// - `bit_vec` is not used concurrently or after this call + /// - `compression` matches one of the allowed enum values + /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or + /// by explicitly calling `sp_command_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_or", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_bitmap_linear_or(nuint offset, BitVec* bit_vec, CompressionCode compression); + + /// + /// Set pixel data according to a xor-mask starting at the offset. + /// + /// The screen will continuously overwrite more pixel data without regarding the offset, meaning + /// once the starting row is full, overwriting will continue on column 0. + /// + /// The contained [SPBitVec] is always uncompressed. + /// + /// The passed [SPBitVec] gets consumed. + /// + /// Returns: a new [Command::BitmapLinearXor] instance. Will never return NULL. + /// + /// # Panics + /// + /// - when `bit_vec` is null + /// - when `compression_code` is not a valid value + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bit_vec` points to a valid instance of [SPBitVec] + /// - `bit_vec` is not used concurrently or after this call + /// - `compression` matches one of the allowed enum values + /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or + /// by explicitly calling `sp_command_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_xor", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_bitmap_linear_xor(nuint offset, BitVec* bit_vec, CompressionCode compression); + + /// + /// Show text on the screen. + /// + /// The passed [SPCp437Grid] gets consumed. + /// + /// Returns: a new [Command::Cp437Data] instance. Will never return NULL. + /// + /// # Panics + /// + /// - when `grid` is null + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `grid` points to a valid instance of [SPCp437Grid] + /// - `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`. + /// + [DllImport(__DllName, EntryPoint = "sp_command_cp437_data", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_cp437_data(nuint x, nuint y, Cp437Grid* grid); + + /// + /// Sets a window of pixels to the specified values. + /// + /// The passed [SPBitmap] gets consumed. + /// + /// Returns: a new [Command::BitmapLinearWin] instance. Will never return NULL. + /// + /// # Panics + /// + /// - when `bitmap` is null + /// - when `compression_code` is not a valid value + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bitmap` points to a valid instance of [SPBitmap] + /// - `bitmap` is not used concurrently or after this call + /// - `compression` matches one of the allowed enum values + /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or + /// by explicitly calling `sp_command_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_win", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_bitmap_linear_win(nuint x, nuint y, Bitmap* bitmap, CompressionCode compression_code); + + /// + /// Deallocates a [SPCommand]. + /// + /// # Examples + /// + /// ```C + /// SPCommand c = sp_command_clear(); + /// sp_command_free(c); + /// ``` + /// + /// # Panics + /// + /// - when `command` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `command` points to a valid [SPCommand] + /// - `command` is not used concurrently or after this call + /// - `command` was not passed to another consuming function, e.g. to create a [SPPacket] + /// + [DllImport(__DllName, EntryPoint = "sp_command_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_command_free(Command* command); + + /// + /// Creates a new [SPBitmap] with the specified dimensions. /// /// # Arguments /// /// - `width`: size in pixels in x-direction /// - `height`: size in pixels in y-direction /// - /// returns: [SPPixelGrid] initialized to all pixels off. Will never return NULL. + /// returns: [SPBitmap] initialized to all pixels off. Will never return NULL. /// /// # Panics /// @@ -1190,20 +1190,20 @@ namespace ServicePoint.BindGen /// 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_pixel_grid_free`. + /// by explicitly calling `sp_bitmap_free`. /// - [DllImport(__DllName, EntryPoint = "sp_pixel_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern PixelGrid* sp_pixel_grid_new(nuint width, nuint height); + [DllImport(__DllName, EntryPoint = "sp_bitmap_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Bitmap* sp_bitmap_new(nuint width, nuint height); /// - /// Loads a [SPPixelGrid] with the specified dimensions from the provided data. + /// Loads a [SPBitmap] with the specified dimensions from the provided data. /// /// # Arguments /// /// - `width`: size in pixels in x-direction /// - `height`: size in pixels in y-direction /// - /// returns: [SPPixelGrid] that contains a copy of the provided data. Will never return NULL. + /// returns: [SPBitmap] that contains a copy of the provided data. Will never return NULL. /// /// # Panics /// @@ -1217,80 +1217,80 @@ namespace ServicePoint.BindGen /// /// - `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_pixel_grid_free`. + /// by explicitly calling `sp_bitmap_free`. /// - [DllImport(__DllName, EntryPoint = "sp_pixel_grid_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern PixelGrid* sp_pixel_grid_load(nuint width, nuint height, byte* data, nuint data_length); + [DllImport(__DllName, EntryPoint = "sp_bitmap_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Bitmap* sp_bitmap_load(nuint width, nuint height, byte* data, nuint data_length); /// - /// Clones a [SPPixelGrid]. + /// Clones a [SPBitmap]. /// /// Will never return NULL. /// /// # Panics /// - /// - when `pixel_grid` is NULL + /// - when `bitmap` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `pixel_grid` points to a valid [SPPixelGrid] - /// - `pixel_grid` is not written to concurrently + /// - `bitmap` points to a valid [SPBitmap] + /// - `bitmap` is not written to concurrently /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_pixel_grid_free`. + /// by explicitly calling `sp_bitmap_free`. /// - [DllImport(__DllName, EntryPoint = "sp_pixel_grid_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern PixelGrid* sp_pixel_grid_clone(PixelGrid* pixel_grid); + [DllImport(__DllName, EntryPoint = "sp_bitmap_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Bitmap* sp_bitmap_clone(Bitmap* bitmap); /// - /// Deallocates a [SPPixelGrid]. + /// Deallocates a [SPBitmap]. /// /// # Panics /// - /// - when `pixel_grid` is NULL + /// - when `bitmap` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `pixel_grid` points to a valid [SPPixelGrid] - /// - `pixel_grid` is not used concurrently or after pixel_grid call - /// - `pixel_grid` was not passed to another consuming function, e.g. to create a [SPCommand] + /// - `bitmap` points to a valid [SPBitmap] + /// - `bitmap` is not used concurrently or after bitmap call + /// - `bitmap` was not passed to another consuming function, e.g. to create a [SPCommand] /// - [DllImport(__DllName, EntryPoint = "sp_pixel_grid_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_pixel_grid_free(PixelGrid* pixel_grid); + [DllImport(__DllName, EntryPoint = "sp_bitmap_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bitmap_free(Bitmap* bitmap); /// - /// Gets the current value at the specified position in the [SPPixelGrid]. + /// Gets the current value at the specified position in the [SPBitmap]. /// /// # Arguments /// - /// - `pixel_grid`: instance to read from + /// - `bitmap`: instance to read from /// - `x` and `y`: position of the cell to read /// /// # Panics /// - /// - when `pixel_grid` is NULL + /// - when `bitmap` is NULL /// - when accessing `x` or `y` out of bounds /// /// # Safety /// /// The caller has to make sure that: /// - /// - `pixel_grid` points to a valid [SPPixelGrid] - /// - `pixel_grid` is not written to concurrently + /// - `bitmap` points to a valid [SPBitmap] + /// - `bitmap` is not written to concurrently /// - [DllImport(__DllName, EntryPoint = "sp_pixel_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + [DllImport(__DllName, EntryPoint = "sp_bitmap_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_pixel_grid_get(PixelGrid* pixel_grid, nuint x, nuint y); + public static extern bool sp_bitmap_get(Bitmap* bitmap, nuint x, nuint y); /// - /// Sets the value of the specified position in the [SPPixelGrid]. + /// Sets the value of the specified position in the [SPBitmap]. /// /// # Arguments /// - /// - `pixel_grid`: instance to write to + /// - `bitmap`: instance to write to /// - `x` and `y`: position of the cell /// - `value`: the value to write to the cell /// @@ -1298,98 +1298,98 @@ namespace ServicePoint.BindGen /// /// # Panics /// - /// - when `pixel_grid` is NULL + /// - when `bitmap` is NULL /// - when accessing `x` or `y` out of bounds /// /// # Safety /// /// The caller has to make sure that: /// - /// - `pixel_grid` points to a valid [SPPixelGrid] - /// - `pixel_grid` is not written to or read from concurrently + /// - `bitmap` points to a valid [SPBitmap] + /// - `bitmap` is not written to or read from concurrently /// - [DllImport(__DllName, EntryPoint = "sp_pixel_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_pixel_grid_set(PixelGrid* pixel_grid, nuint x, nuint y, [MarshalAs(UnmanagedType.U1)] bool value); + [DllImport(__DllName, EntryPoint = "sp_bitmap_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bitmap_set(Bitmap* bitmap, nuint x, nuint y, [MarshalAs(UnmanagedType.U1)] bool value); /// - /// Sets the state of all pixels in the [SPPixelGrid]. + /// Sets the state of all pixels in the [SPBitmap]. /// /// # Arguments /// - /// - `pixel_grid`: instance to write to + /// - `bitmap`: instance to write to /// - `value`: the value to set all pixels to /// /// # Panics /// - /// - when `pixel_grid` is NULL + /// - when `bitmap` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `pixel_grid` points to a valid [SPPixelGrid] - /// - `pixel_grid` is not written to or read from concurrently + /// - `bitmap` points to a valid [SPBitmap] + /// - `bitmap` is not written to or read from concurrently /// - [DllImport(__DllName, EntryPoint = "sp_pixel_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_pixel_grid_fill(PixelGrid* pixel_grid, [MarshalAs(UnmanagedType.U1)] bool value); + [DllImport(__DllName, EntryPoint = "sp_bitmap_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bitmap_fill(Bitmap* bitmap, [MarshalAs(UnmanagedType.U1)] bool value); /// - /// Gets the width in pixels of the [SPPixelGrid] instance. + /// Gets the width in pixels of the [SPBitmap] instance. /// /// # Arguments /// - /// - `pixel_grid`: instance to read from + /// - `bitmap`: instance to read from /// /// # Panics /// - /// - when `pixel_grid` is NULL + /// - when `bitmap` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `pixel_grid` points to a valid [SPPixelGrid] + /// - `bitmap` points to a valid [SPBitmap] /// - [DllImport(__DllName, EntryPoint = "sp_pixel_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_pixel_grid_width(PixelGrid* pixel_grid); + [DllImport(__DllName, EntryPoint = "sp_bitmap_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern nuint sp_bitmap_width(Bitmap* bitmap); /// - /// Gets the height in pixels of the [SPPixelGrid] instance. + /// Gets the height in pixels of the [SPBitmap] instance. /// /// # Arguments /// - /// - `pixel_grid`: instance to read from + /// - `bitmap`: instance to read from /// /// # Panics /// - /// - when `pixel_grid` is NULL + /// - when `bitmap` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `pixel_grid` points to a valid [SPPixelGrid] + /// - `bitmap` points to a valid [SPBitmap] /// - [DllImport(__DllName, EntryPoint = "sp_pixel_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_pixel_grid_height(PixelGrid* pixel_grid); + [DllImport(__DllName, EntryPoint = "sp_bitmap_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern nuint sp_bitmap_height(Bitmap* bitmap); /// - /// Gets an unsafe reference to the data of the [SPPixelGrid] instance. + /// Gets an unsafe reference to the data of the [SPBitmap] instance. /// /// # Panics /// - /// - when `pixel_grid` is NULL + /// - when `bitmap` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `pixel_grid` points to a valid [SPPixelGrid] - /// - the returned memory range is never accessed after the passed [SPPixelGrid] has been freed - /// - the returned memory range is never accessed concurrently, either via the [SPPixelGrid] or directly + /// - `bitmap` points to a valid [SPBitmap] + /// - the returned memory range is never accessed after the passed [SPBitmap] has been freed + /// - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly /// - [DllImport(__DllName, EntryPoint = "sp_pixel_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteSlice sp_pixel_grid_unsafe_data_ref(PixelGrid* pixel_grid); + [DllImport(__DllName, EntryPoint = "sp_bitmap_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern ByteSlice sp_bitmap_unsafe_data_ref(Bitmap* bitmap); } @@ -1411,11 +1411,6 @@ namespace ServicePoint.BindGen public nuint length; } - [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct Command - { - } - [StructLayout(LayoutKind.Sequential)] public unsafe partial struct Connection { @@ -1432,7 +1427,12 @@ namespace ServicePoint.BindGen } [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct PixelGrid + public unsafe partial struct Command + { + } + + [StructLayout(LayoutKind.Sequential)] + public unsafe partial struct Bitmap { } diff --git a/crates/servicepoint_binding_cs/ServicePoint/PixelGrid.cs b/crates/servicepoint_binding_cs/ServicePoint/Bitmap.cs similarity index 50% rename from crates/servicepoint_binding_cs/ServicePoint/PixelGrid.cs rename to crates/servicepoint_binding_cs/ServicePoint/Bitmap.cs index 77e0cf3..6747483 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/PixelGrid.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/Bitmap.cs @@ -2,33 +2,33 @@ using ServicePoint.BindGen; namespace ServicePoint; -public sealed class PixelGrid : SpNativeInstance +public sealed class Bitmap : SpNativeInstance { - public static PixelGrid New(int width, int height) + public static Bitmap New(int width, int height) { unsafe { - return new PixelGrid(NativeMethods.sp_pixel_grid_new((nuint)width, (nuint)height)); + return new Bitmap(NativeMethods.sp_bitmap_new((nuint)width, (nuint)height)); } } - public static PixelGrid Load(int width, int height, Span bytes) + public static Bitmap Load(int width, int height, Span bytes) { unsafe { fixed (byte* bytesPtr = bytes) { - return new PixelGrid(NativeMethods.sp_pixel_grid_load((nuint)width, (nuint)height, bytesPtr, + return new Bitmap(NativeMethods.sp_bitmap_load((nuint)width, (nuint)height, bytesPtr, (nuint)bytes.Length)); } } } - public PixelGrid Clone() + public Bitmap Clone() { unsafe { - return new PixelGrid(NativeMethods.sp_pixel_grid_clone(Instance)); + return new Bitmap(NativeMethods.sp_bitmap_clone(Instance)); } } @@ -38,14 +38,14 @@ public sealed class PixelGrid : SpNativeInstance { unsafe { - return NativeMethods.sp_pixel_grid_get(Instance, (nuint)x, (nuint)y); + return NativeMethods.sp_bitmap_get(Instance, (nuint)x, (nuint)y); } } set { unsafe { - NativeMethods.sp_pixel_grid_set(Instance, (nuint)x, (nuint)y, value); + NativeMethods.sp_bitmap_set(Instance, (nuint)x, (nuint)y, value); } } } @@ -54,7 +54,7 @@ public sealed class PixelGrid : SpNativeInstance { unsafe { - NativeMethods.sp_pixel_grid_fill(Instance, value); + NativeMethods.sp_bitmap_fill(Instance, value); } } @@ -64,7 +64,7 @@ public sealed class PixelGrid : SpNativeInstance { unsafe { - return (int)NativeMethods.sp_pixel_grid_width(Instance); + return (int)NativeMethods.sp_bitmap_width(Instance); } } } @@ -75,7 +75,7 @@ public sealed class PixelGrid : SpNativeInstance { unsafe { - return (int)NativeMethods.sp_pixel_grid_height(Instance); + return (int)NativeMethods.sp_bitmap_height(Instance); } } } @@ -86,15 +86,15 @@ public sealed class PixelGrid : SpNativeInstance { unsafe { - var slice = NativeMethods.sp_pixel_grid_unsafe_data_ref(Instance); + var slice = NativeMethods.sp_bitmap_unsafe_data_ref(Instance); return new Span(slice.start, (int)slice.length); } } } - private unsafe PixelGrid(BindGen.PixelGrid* instance) : base(instance) + private unsafe Bitmap(BindGen.Bitmap* instance) : base(instance) { } - private protected override unsafe void Free() => NativeMethods.sp_pixel_grid_free(Instance); + private protected override unsafe void Free() => NativeMethods.sp_bitmap_free(Instance); } diff --git a/crates/servicepoint_binding_cs/ServicePoint/Command.cs b/crates/servicepoint_binding_cs/ServicePoint/Command.cs index e17c685..b62d511 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/Command.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/Command.cs @@ -105,11 +105,11 @@ public sealed class Command : SpNativeInstance } } - public static Command BitmapLinearWin(int x, int y, PixelGrid pixelGrid, CompressionCode compression) + public static Command BitmapLinearWin(int x, int y, Bitmap bitmap, CompressionCode compression) { unsafe { - return new Command(NativeMethods.sp_command_bitmap_linear_win((ushort)x, (ushort)y, pixelGrid.Into(), compression)); + return new Command(NativeMethods.sp_command_bitmap_linear_win((ushort)x, (ushort)y, bitmap.Into(), compression)); } } diff --git a/crates/servicepoint_binding_cs/examples/lang_cs/Program.cs b/crates/servicepoint_binding_cs/examples/lang_cs/Program.cs index adfc32e..89c0eef 100644 --- a/crates/servicepoint_binding_cs/examples/lang_cs/Program.cs +++ b/crates/servicepoint_binding_cs/examples/lang_cs/Program.cs @@ -6,7 +6,7 @@ using var connection = Connection.Open("127.0.0.1:2342"); connection.Send(Command.Clear().IntoPacket()); connection.Send(Command.Brightness(128).IntoPacket()); -using var pixels = PixelGrid.New(Constants.PixelWidth, Constants.PixelHeight); +using var pixels = Bitmap.New(Constants.PixelWidth, Constants.PixelHeight); for (var offset = 0; offset < int.MaxValue; offset++) { From 593a975d5c15b72b892c4fe0d90022de9779a866 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Tue, 15 Oct 2024 21:26:20 +0200 Subject: [PATCH 15/27] rename convert to map also use the fact that T is known to be Copy --- crates/servicepoint/src/cp437.rs | 6 +++--- crates/servicepoint/src/primitive_grid.rs | 14 ++++++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/crates/servicepoint/src/cp437.rs b/crates/servicepoint/src/cp437.rs index c6df59c..f757594 100644 --- a/crates/servicepoint/src/cp437.rs +++ b/crates/servicepoint/src/cp437.rs @@ -129,17 +129,17 @@ mod feature_cp437 { HashMap::from_iter(pairs) }); - const MISSING_CHAR_CP437: u8 = 0x3F; + const MISSING_CHAR_CP437: u8 = 0x3F; // '?' impl From<&Cp437Grid> for CharGrid { fn from(value: &Cp437Grid) -> Self { - value.convert(move |cp437| cp437_to_char(*cp437)) + value.map(cp437_to_char) } } impl From<&CharGrid> for Cp437Grid { fn from(value: &CharGrid) -> Self { - value.convert(move |char| char_to_cp437(*char)) + value.map(char_to_cp437) } } diff --git a/crates/servicepoint/src/primitive_grid.rs b/crates/servicepoint/src/primitive_grid.rs index ca2ce05..f58c44c 100644 --- a/crates/servicepoint/src/primitive_grid.rs +++ b/crates/servicepoint/src/primitive_grid.rs @@ -111,13 +111,19 @@ impl PrimitiveGrid { } } - /// Convert between PrimitiveGrid types - pub fn convert(&self, f: F) -> PrimitiveGrid + /// Convert between PrimitiveGrid types. + /// + /// See also [Iterator::map]. + pub fn map(&self, f: F) -> PrimitiveGrid where TConverted: PrimitiveGridType, - F: FnMut(&T) -> TConverted, + F: Fn(T) -> TConverted, { - let data = self.data_ref().iter().map(f).collect::>(); + let data = self + .data_ref() + .iter() + .map(|elem| f(*elem)) + .collect::>(); PrimitiveGrid::load(self.width(), self.height(), &data) } } From 78a4d4dbcfaa41930248b6def97c2f125d03ecfd Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Tue, 15 Oct 2024 21:32:37 +0200 Subject: [PATCH 16/27] add Brightness::saturating_from --- .../servicepoint/examples/brightness_tester.rs | 5 +++-- crates/servicepoint/src/brightness.rs | 17 +++++++++++++++++ crates/servicepoint/src/primitive_grid.rs | 12 ++++++++++++ .../src/brightness_grid.rs | 7 +------ 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/crates/servicepoint/examples/brightness_tester.rs b/crates/servicepoint/examples/brightness_tester.rs index 16fbf61..09e1ed6 100644 --- a/crates/servicepoint/examples/brightness_tester.rs +++ b/crates/servicepoint/examples/brightness_tester.rs @@ -25,10 +25,11 @@ fn main() { ); connection.send(command).expect("send failed"); - let max_brightness = usize::from(u8::from(Brightness::MAX)); + let max_brightness: u8 = Brightness::MAX.into(); let mut brightnesses = BrightnessGrid::new(TILE_WIDTH, TILE_HEIGHT); for (index, byte) in brightnesses.data_ref_mut().iter_mut().enumerate() { - *byte = Brightness::try_from((index % max_brightness) as u8).unwrap(); + let level = index as u8 % max_brightness; + *byte = Brightness::try_from(level).unwrap(); } connection diff --git a/crates/servicepoint/src/brightness.rs b/crates/servicepoint/src/brightness.rs index ad07aa6..e5a82b3 100644 --- a/crates/servicepoint/src/brightness.rs +++ b/crates/servicepoint/src/brightness.rs @@ -60,6 +60,17 @@ impl Brightness { pub const MAX: Brightness = Brightness(11); /// lowest possible brightness value, 0 pub const MIN: Brightness = Brightness(0); + + /// Create a brightness value without returning an error for brightnesses above [Brightness::MAX]. + /// + /// returns: the specified value as a [Brightness], or [Brightness::MAX]. + pub fn saturating_from(value: u8) -> Brightness { + if value > Brightness::MAX.into() { + Brightness::MAX + } else { + Brightness(value) + } + } } impl Default for Brightness { @@ -138,4 +149,10 @@ mod tests { let actual = PrimitiveGrid::from(&grid); assert_eq!(actual.data_ref(), &[11, 0, 11, 11]); } + + #[test] + fn saturating_convert() { + assert_eq!(Brightness::MAX, Brightness::saturating_from(100)); + assert_eq!(Brightness(5), Brightness::saturating_from(5)); + } } diff --git a/crates/servicepoint/src/primitive_grid.rs b/crates/servicepoint/src/primitive_grid.rs index f58c44c..69dcf0f 100644 --- a/crates/servicepoint/src/primitive_grid.rs +++ b/crates/servicepoint/src/primitive_grid.rs @@ -114,6 +114,18 @@ impl PrimitiveGrid { /// Convert between PrimitiveGrid types. /// /// See also [Iterator::map]. + /// + /// # Examples + /// + /// Use logic written for u8s and then convert to [Brightness] values for sending in a [Command]. + /// ``` + /// # fn foo(grid: &mut PrimitiveGrid) {} + /// # use servicepoint::{Brightness, BrightnessGrid, Command, Origin, PrimitiveGrid, TILE_HEIGHT, TILE_WIDTH}; + /// let mut grid: PrimitiveGrid = PrimitiveGrid::new(TILE_WIDTH, TILE_HEIGHT); + /// foo(&mut grid); + /// let grid: BrightnessGrid = grid.map(Brightness::saturating_from); + /// let command = Command::CharBrightness(Origin::ZERO, grid); + /// ``` pub fn map(&self, f: F) -> PrimitiveGrid where TConverted: PrimitiveGridType, diff --git a/crates/servicepoint_binding_c/src/brightness_grid.rs b/crates/servicepoint_binding_c/src/brightness_grid.rs index db44687..c1dc186 100644 --- a/crates/servicepoint_binding_c/src/brightness_grid.rs +++ b/crates/servicepoint_binding_c/src/brightness_grid.rs @@ -21,14 +21,9 @@ use std::intrinsics::transmute; /// SPCommand command = sp_command_char_brightness(grid); /// sp_connection_free(connection); /// ``` +#[derive(Clone)] pub struct SPBrightnessGrid(pub(crate) servicepoint::BrightnessGrid); -impl Clone for SPBrightnessGrid { - fn clone(&self) -> Self { - SPBrightnessGrid(self.0.clone()) - } -} - /// Creates a new [SPBrightnessGrid] with the specified dimensions. /// /// returns: [SPBrightnessGrid] initialized to 0. Will never return NULL. From a08d43936672f5317798f4a57ad2e10b88ef5002 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Tue, 15 Oct 2024 21:33:32 +0200 Subject: [PATCH 17/27] formatting changes, mostly resulting from the shorter name --- crates/servicepoint/examples/websocket.rs | 2 +- crates/servicepoint/src/bitmap.rs | 2 +- crates/servicepoint/src/command.rs | 7 +- crates/servicepoint/src/lib.rs | 4 +- crates/servicepoint/src/packet.rs | 4 +- crates/servicepoint_binding_c/src/bitmap.rs | 13 +-- crates/servicepoint_binding_c/src/command.rs | 97 +++++++++++-------- .../servicepoint_binding_c/src/cp437_grid.rs | 12 +-- crates/servicepoint_binding_c/src/lib.rs | 4 +- 9 files changed, 75 insertions(+), 70 deletions(-) diff --git a/crates/servicepoint/examples/websocket.rs b/crates/servicepoint/examples/websocket.rs index b982633..a0c43c0 100644 --- a/crates/servicepoint/examples/websocket.rs +++ b/crates/servicepoint/examples/websocket.rs @@ -1,7 +1,7 @@ //! Example for how to use the WebSocket connection use servicepoint::{ - Command, CompressionCode, Connection, Grid, Origin, Bitmap, + Bitmap, Command, CompressionCode, Connection, Grid, Origin, }; fn main() { diff --git a/crates/servicepoint/src/bitmap.rs b/crates/servicepoint/src/bitmap.rs index 9eabf96..657e155 100644 --- a/crates/servicepoint/src/bitmap.rs +++ b/crates/servicepoint/src/bitmap.rs @@ -197,7 +197,7 @@ impl<'t> Iterator for IterRows<'t> { #[cfg(test)] mod tests { - use crate::{DataRef, Grid, Bitmap}; + use crate::{Bitmap, DataRef, Grid}; #[test] fn fill() { diff --git a/crates/servicepoint/src/command.rs b/crates/servicepoint/src/command.rs index 94a161a..51235fd 100644 --- a/crates/servicepoint/src/command.rs +++ b/crates/servicepoint/src/command.rs @@ -4,7 +4,7 @@ use crate::{ command_code::CommandCode, compression::into_decompressed, packet::{Header, Packet}, - Brightness, BrightnessGrid, CompressionCode, Cp437Grid, Origin, Bitmap, + Bitmap, Brightness, BrightnessGrid, CompressionCode, Cp437Grid, Origin, Pixels, PrimitiveGrid, SpBitVec, Tiles, TILE_SIZE, }; @@ -495,8 +495,8 @@ mod tests { command_code::CommandCode, origin::Pixels, packet::{Header, Packet}, - Brightness, BrightnessGrid, Command, CompressionCode, Origin, - Bitmap, PrimitiveGrid, + Bitmap, Brightness, BrightnessGrid, Command, CompressionCode, Origin, + PrimitiveGrid, }; fn round_trip(original: Command) { @@ -903,6 +903,7 @@ mod tests { Origin::new(1, 0) + Origin::new(3, 2) ); } + #[test] fn packet_into_char_brightness_invalid() { let grid = BrightnessGrid::new(2, 2); diff --git a/crates/servicepoint/src/lib.rs b/crates/servicepoint/src/lib.rs index 0d8e871..3848967 100644 --- a/crates/servicepoint/src/lib.rs +++ b/crates/servicepoint/src/lib.rs @@ -40,6 +40,7 @@ use std::time::Duration; pub use bitvec; use bitvec::prelude::{BitVec, Msb0}; +pub use crate::bitmap::Bitmap; pub use crate::brightness::{Brightness, BrightnessGrid}; pub use crate::command::{Command, Offset}; pub use crate::compression_code::CompressionCode; @@ -48,11 +49,11 @@ pub use crate::cp437::{CharGrid, Cp437Grid}; pub use crate::data_ref::DataRef; pub use crate::grid::Grid; pub use crate::origin::{Origin, Pixels, Tiles}; -pub use crate::bitmap::Bitmap; pub use crate::primitive_grid::PrimitiveGrid; type SpBitVec = BitVec; +mod bitmap; mod brightness; mod command; mod command_code; @@ -64,7 +65,6 @@ mod data_ref; mod grid; mod origin; pub mod packet; -mod bitmap; mod primitive_grid; /// size of a single tile in one dimension diff --git a/crates/servicepoint/src/packet.rs b/crates/servicepoint/src/packet.rs index 87fd8b6..2b8688d 100644 --- a/crates/servicepoint/src/packet.rs +++ b/crates/servicepoint/src/packet.rs @@ -27,8 +27,8 @@ use std::mem::size_of; use crate::compression::into_compressed; use crate::{ - command_code::CommandCode, Command, CompressionCode, Grid, Offset, Origin, - Bitmap, Pixels, Tiles, TILE_SIZE, + command_code::CommandCode, Bitmap, Command, CompressionCode, Grid, Offset, + Origin, Pixels, Tiles, TILE_SIZE, }; /// A raw header. diff --git a/crates/servicepoint_binding_c/src/bitmap.rs b/crates/servicepoint_binding_c/src/bitmap.rs index 22d9a57..0c4271c 100644 --- a/crates/servicepoint_binding_c/src/bitmap.rs +++ b/crates/servicepoint_binding_c/src/bitmap.rs @@ -210,10 +210,7 @@ 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 SPBitmap, - value: bool, -) { +pub unsafe extern "C" fn sp_bitmap_fill(bitmap: *mut SPBitmap, value: bool) { assert!(!bitmap.is_null()); (*bitmap).0.fill(value); } @@ -234,9 +231,7 @@ pub unsafe extern "C" fn sp_bitmap_fill( /// /// - `bitmap` points to a valid [SPBitmap] #[no_mangle] -pub unsafe extern "C" fn sp_bitmap_width( - bitmap: *const SPBitmap, -) -> usize { +pub unsafe extern "C" fn sp_bitmap_width(bitmap: *const SPBitmap) -> usize { assert!(!bitmap.is_null()); (*bitmap).0.width() } @@ -257,9 +252,7 @@ pub unsafe extern "C" fn sp_bitmap_width( /// /// - `bitmap` points to a valid [SPBitmap] #[no_mangle] -pub unsafe extern "C" fn sp_bitmap_height( - bitmap: *const SPBitmap, -) -> usize { +pub unsafe extern "C" fn sp_bitmap_height(bitmap: *const SPBitmap) -> usize { assert!(!bitmap.is_null()); (*bitmap).0.height() } diff --git a/crates/servicepoint_binding_c/src/command.rs b/crates/servicepoint_binding_c/src/command.rs index 4a64829..db86551 100644 --- a/crates/servicepoint_binding_c/src/command.rs +++ b/crates/servicepoint_binding_c/src/command.rs @@ -7,8 +7,8 @@ use std::ptr::null_mut; use servicepoint::{Brightness, Origin}; use crate::{ - SPBitVec, SPBrightnessGrid, SPCompressionCode, SPCp437Grid, SPPacket, - SPBitmap, + SPBitVec, SPBitmap, SPBrightnessGrid, SPCompressionCode, SPCp437Grid, + SPPacket, }; /// A low-level display command. @@ -107,7 +107,8 @@ pub unsafe extern "C" fn sp_command_clone( /// by explicitly calling `sp_command_free`. #[no_mangle] pub unsafe extern "C" fn sp_command_clear() -> *mut SPCommand { - let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::Clear))); + let result = + Box::into_raw(Box::new(SPCommand(servicepoint::Command::Clear))); assert!(!result.is_null()); result } @@ -126,7 +127,8 @@ pub unsafe extern "C" fn sp_command_clear() -> *mut SPCommand { /// by explicitly calling `sp_command_free`. #[no_mangle] pub unsafe extern "C" fn sp_command_hard_reset() -> *mut SPCommand { - let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::HardReset))); + let result = + Box::into_raw(Box::new(SPCommand(servicepoint::Command::HardReset))); assert!(!result.is_null()); result } @@ -143,7 +145,8 @@ pub unsafe extern "C" fn sp_command_hard_reset() -> *mut SPCommand { /// by explicitly calling `sp_command_free`. #[no_mangle] pub unsafe extern "C" fn sp_command_fade_out() -> *mut SPCommand { - let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::FadeOut))); + let result = + Box::into_raw(Box::new(SPCommand(servicepoint::Command::FadeOut))); assert!(!result.is_null()); result } @@ -168,9 +171,9 @@ pub unsafe extern "C" fn sp_command_brightness( ) -> *mut SPCommand { let brightness = Brightness::try_from(brightness).expect("invalid brightness"); - let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::Brightness( - brightness, - )))); + let result = Box::into_raw(Box::new(SPCommand( + servicepoint::Command::Brightness(brightness), + ))); assert!(!result.is_null()); result } @@ -201,10 +204,9 @@ pub unsafe extern "C" fn sp_command_char_brightness( ) -> *mut SPCommand { assert!(!grid.is_null()); let byte_grid = *Box::from_raw(grid); - let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::CharBrightness( - Origin::new(x, y), - byte_grid.0, - )))); + let result = Box::into_raw(Box::new(SPCommand( + servicepoint::Command::CharBrightness(Origin::new(x, y), byte_grid.0), + ))); assert!(!result.is_null()); result } @@ -242,11 +244,13 @@ pub unsafe extern "C" fn sp_command_bitmap_linear( ) -> *mut SPCommand { assert!(!bit_vec.is_null()); let bit_vec = *Box::from_raw(bit_vec); - let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinear( - offset, - bit_vec.into(), - compression.try_into().expect("invalid compression code"), - )))); + let result = Box::into_raw(Box::new(SPCommand( + servicepoint::Command::BitmapLinear( + offset, + bit_vec.into(), + compression.try_into().expect("invalid compression code"), + ), + ))); assert!(!result.is_null()); result } @@ -284,11 +288,13 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_and( ) -> *mut SPCommand { assert!(!bit_vec.is_null()); let bit_vec = *Box::from_raw(bit_vec); - let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinearAnd( - offset, - bit_vec.into(), - compression.try_into().expect("invalid compression code"), - )))); + let result = Box::into_raw(Box::new(SPCommand( + servicepoint::Command::BitmapLinearAnd( + offset, + bit_vec.into(), + compression.try_into().expect("invalid compression code"), + ), + ))); assert!(!result.is_null()); result } @@ -326,11 +332,13 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_or( ) -> *mut SPCommand { assert!(!bit_vec.is_null()); let bit_vec = *Box::from_raw(bit_vec); - let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinearOr( - offset, - bit_vec.into(), - compression.try_into().expect("invalid compression code"), - )))); + let result = Box::into_raw(Box::new(SPCommand( + servicepoint::Command::BitmapLinearOr( + offset, + bit_vec.into(), + compression.try_into().expect("invalid compression code"), + ), + ))); assert!(!result.is_null()); result } @@ -368,11 +376,13 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_xor( ) -> *mut SPCommand { assert!(!bit_vec.is_null()); let bit_vec = *Box::from_raw(bit_vec); - let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinearXor( - offset, - bit_vec.into(), - compression.try_into().expect("invalid compression code"), - )))); + let result = Box::into_raw(Box::new(SPCommand( + servicepoint::Command::BitmapLinearXor( + offset, + bit_vec.into(), + compression.try_into().expect("invalid compression code"), + ), + ))); assert!(!result.is_null()); result } @@ -403,10 +413,9 @@ pub unsafe extern "C" fn sp_command_cp437_data( ) -> *mut SPCommand { assert!(!grid.is_null()); let grid = *Box::from_raw(grid); - let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::Cp437Data( - Origin::new(x, y), - grid.0, - )))); + let result = Box::into_raw(Box::new(SPCommand( + servicepoint::Command::Cp437Data(Origin::new(x, y), grid.0), + ))); assert!(!result.is_null()); result } @@ -440,13 +449,15 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_win( ) -> *mut SPCommand { assert!(!bitmap.is_null()); let byte_grid = (*Box::from_raw(bitmap)).0; - let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinearWin( - Origin::new(x, y), - byte_grid, - compression_code - .try_into() - .expect("invalid compression code"), - )))); + let result = Box::into_raw(Box::new(SPCommand( + servicepoint::Command::BitmapLinearWin( + Origin::new(x, y), + byte_grid, + compression_code + .try_into() + .expect("invalid compression code"), + ), + ))); assert!(!result.is_null()); result } diff --git a/crates/servicepoint_binding_c/src/cp437_grid.rs b/crates/servicepoint_binding_c/src/cp437_grid.rs index 791c594..e458a1b 100644 --- a/crates/servicepoint_binding_c/src/cp437_grid.rs +++ b/crates/servicepoint_binding_c/src/cp437_grid.rs @@ -40,9 +40,9 @@ pub unsafe extern "C" fn sp_cp437_grid_new( width: usize, height: usize, ) -> *mut SPCp437Grid { - let result = Box::into_raw(Box::new(SPCp437Grid(servicepoint::Cp437Grid::new( - width, height, - )))); + let result = Box::into_raw(Box::new(SPCp437Grid( + servicepoint::Cp437Grid::new(width, height), + ))); assert!(!result.is_null()); result } @@ -73,9 +73,9 @@ pub unsafe extern "C" fn sp_cp437_grid_load( ) -> *mut SPCp437Grid { assert!(data.is_null()); let data = std::slice::from_raw_parts(data, data_length); - let result = Box::into_raw(Box::new(SPCp437Grid(servicepoint::Cp437Grid::load( - width, height, data, - )))); + let result = Box::into_raw(Box::new(SPCp437Grid( + servicepoint::Cp437Grid::load(width, height, data), + ))); assert!(!result.is_null()); result } diff --git a/crates/servicepoint_binding_c/src/lib.rs b/crates/servicepoint_binding_c/src/lib.rs index 7698252..2c9006d 100644 --- a/crates/servicepoint_binding_c/src/lib.rs +++ b/crates/servicepoint_binding_c/src/lib.rs @@ -26,6 +26,7 @@ //! ``` pub use crate::bit_vec::*; +pub use crate::bitmap::*; pub use crate::brightness_grid::*; pub use crate::byte_slice::*; pub use crate::command::*; @@ -33,9 +34,9 @@ pub use crate::connection::*; pub use crate::constants::*; pub use crate::cp437_grid::*; pub use crate::packet::*; -pub use crate::bitmap::*; mod bit_vec; +mod bitmap; mod brightness_grid; mod byte_slice; mod command; @@ -43,4 +44,3 @@ mod connection; mod constants; mod cp437_grid; mod packet; -mod bitmap; From fbc8cd6c31b6c2377fb1702ca7622433485a0f92 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Tue, 15 Oct 2024 21:50:43 +0200 Subject: [PATCH 18/27] rename sp_bit_vec_* to sp_bitvec_* --- Cargo.lock | 4 +- crates/servicepoint/examples/wiping_clear.rs | 2 +- .../examples/lang_c/include/servicepoint.h | 32 ++++++------- crates/servicepoint_binding_c/src/bit_vec.rs | 34 +++++++------- .../ServicePoint/BindGen/ServicePoint.g.cs | 46 +++++++++---------- .../ServicePoint/BitVec.cs | 18 ++++---- 6 files changed, 68 insertions(+), 68 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 45d9e17..10ec770 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -147,9 +147,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.29" +version = "1.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58e804ac3194a48bb129643eb1d62fcc20d18c6b8c181704489353d13120bcd1" +checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" dependencies = [ "jobserver", "libc", diff --git a/crates/servicepoint/examples/wiping_clear.rs b/crates/servicepoint/examples/wiping_clear.rs index c28345d..a3bf04a 100644 --- a/crates/servicepoint/examples/wiping_clear.rs +++ b/crates/servicepoint/examples/wiping_clear.rs @@ -25,7 +25,7 @@ fn main() { let connection = Connection::open(cli.destination) .expect("could not connect to display"); - let mut enabled_pixels = Bitmap::new(PIXEL_WIDTH, PIXEL_HEIGHT); + let mut enabled_pixels = Bitmap::max_sized(); enabled_pixels.fill(true); for x_offset in 0..PIXEL_WIDTH { diff --git a/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h b/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h index b0a420b..e85a9fa 100644 --- a/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h +++ b/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h @@ -76,9 +76,9 @@ typedef uint16_t SPCompressionCode; * * # Examples * ```C - * SPBitVec vec = sp_bit_vec_new(8); - * sp_bit_vec_set(vec, 5, true); - * sp_bit_vec_free(vec); + * SPBitVec vec = sp_bitvec_new(8); + * sp_bitvec_set(vec, 5, true); + * sp_bitvec_free(vec); * ``` */ typedef struct SPBitVec SPBitVec; @@ -212,9 +212,9 @@ extern "C" { * - `bit_vec` points to a valid [SPBitVec] * - `bit_vec` is not written to concurrently * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_bit_vec_free`. + * by explicitly calling `sp_bitvec_free`. */ -struct SPBitVec *sp_bit_vec_clone(const struct SPBitVec *bit_vec); +struct SPBitVec *sp_bitvec_clone(const struct SPBitVec *bit_vec); /** * Sets the value of all bits in the [SPBitVec]. @@ -235,7 +235,7 @@ struct SPBitVec *sp_bit_vec_clone(const struct SPBitVec *bit_vec); * - `bit_vec` points to a valid [SPBitVec] * - `bit_vec` is not written to or read from concurrently */ -void sp_bit_vec_fill(struct SPBitVec *bit_vec, bool value); +void sp_bitvec_fill(struct SPBitVec *bit_vec, bool value); /** * Deallocates a [SPBitVec]. @@ -252,7 +252,7 @@ void sp_bit_vec_fill(struct SPBitVec *bit_vec, bool value); * - `bit_vec` is not used concurrently or after this call * - `bit_vec` was not passed to another consuming function, e.g. to create a [SPCommand] */ -void sp_bit_vec_free(struct SPBitVec *bit_vec); +void sp_bitvec_free(struct SPBitVec *bit_vec); /** * Gets the value of a bit from the [SPBitVec]. @@ -276,7 +276,7 @@ void sp_bit_vec_free(struct SPBitVec *bit_vec); * - `bit_vec` points to a valid [SPBitVec] * - `bit_vec` is not written to concurrently */ -bool sp_bit_vec_get(const struct SPBitVec *bit_vec, size_t index); +bool sp_bitvec_get(const struct SPBitVec *bit_vec, size_t index); /** * Returns true if length is 0. @@ -295,7 +295,7 @@ bool sp_bit_vec_get(const struct SPBitVec *bit_vec, size_t index); * * - `bit_vec` points to a valid [SPBitVec] */ -bool sp_bit_vec_is_empty(const struct SPBitVec *bit_vec); +bool sp_bitvec_is_empty(const struct SPBitVec *bit_vec); /** * Gets the length of the [SPBitVec] in bits. @@ -314,7 +314,7 @@ bool sp_bit_vec_is_empty(const struct SPBitVec *bit_vec); * * - `bit_vec` points to a valid [SPBitVec] */ -size_t sp_bit_vec_len(const struct SPBitVec *bit_vec); +size_t sp_bitvec_len(const struct SPBitVec *bit_vec); /** * Interpret the data as a series of bits and load then into a new [SPBitVec] instance. @@ -332,9 +332,9 @@ size_t sp_bit_vec_len(const struct SPBitVec *bit_vec); * - `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_bit_vec_free`. + * by explicitly calling `sp_bitvec_free`. */ -struct SPBitVec *sp_bit_vec_load(const uint8_t *data, +struct SPBitVec *sp_bitvec_load(const uint8_t *data, size_t data_length); /** @@ -355,9 +355,9 @@ struct SPBitVec *sp_bit_vec_load(const uint8_t *data, * 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_bit_vec_free`. + * by explicitly calling `sp_bitvec_free`. */ -struct SPBitVec *sp_bit_vec_new(size_t size); +struct SPBitVec *sp_bitvec_new(size_t size); /** * Sets the value of a bit in the [SPBitVec]. @@ -380,7 +380,7 @@ struct SPBitVec *sp_bit_vec_new(size_t size); * - `bit_vec` points to a valid [SPBitVec] * - `bit_vec` is not written to or read from concurrently */ -void sp_bit_vec_set(struct SPBitVec *bit_vec, size_t index, bool value); +void sp_bitvec_set(struct SPBitVec *bit_vec, size_t index, bool value); /** * Gets an unsafe reference to the data of the [SPBitVec] instance. @@ -401,7 +401,7 @@ void sp_bit_vec_set(struct SPBitVec *bit_vec, size_t index, bool value); * - the returned memory range is never accessed after the passed [SPBitVec] has been freed * - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly */ -struct SPByteSlice sp_bit_vec_unsafe_data_ref(struct SPBitVec *bit_vec); +struct SPByteSlice sp_bitvec_unsafe_data_ref(struct SPBitVec *bit_vec); /** * Clones a [SPBitmap]. diff --git a/crates/servicepoint_binding_c/src/bit_vec.rs b/crates/servicepoint_binding_c/src/bit_vec.rs index 8b9e94f..1fe509b 100644 --- a/crates/servicepoint_binding_c/src/bit_vec.rs +++ b/crates/servicepoint_binding_c/src/bit_vec.rs @@ -1,6 +1,6 @@ //! C functions for interacting with [SPBitVec]s //! -//! prefix `sp_bit_vec_` +//! prefix `sp_bitvec_` use crate::SPByteSlice; use servicepoint::bitvec::prelude::{BitVec, Msb0}; @@ -9,9 +9,9 @@ use servicepoint::bitvec::prelude::{BitVec, Msb0}; /// /// # Examples /// ```C -/// SPBitVec vec = sp_bit_vec_new(8); -/// sp_bit_vec_set(vec, 5, true); -/// sp_bit_vec_free(vec); +/// SPBitVec vec = sp_bitvec_new(8); +/// sp_bitvec_set(vec, 5, true); +/// sp_bitvec_free(vec); /// ``` pub struct SPBitVec(BitVec); @@ -50,9 +50,9 @@ impl Clone for SPBitVec { /// 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_bit_vec_free`. +/// by explicitly calling `sp_bitvec_free`. #[no_mangle] -pub unsafe extern "C" fn sp_bit_vec_new(size: usize) -> *mut SPBitVec { +pub unsafe extern "C" fn sp_bitvec_new(size: usize) -> *mut SPBitVec { let result = Box::into_raw(Box::new(SPBitVec(BitVec::repeat(false, size)))); assert!(!result.is_null()); result @@ -73,9 +73,9 @@ pub unsafe extern "C" fn sp_bit_vec_new(size: usize) -> *mut SPBitVec { /// - `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_bit_vec_free`. +/// by explicitly calling `sp_bitvec_free`. #[no_mangle] -pub unsafe extern "C" fn sp_bit_vec_load( +pub unsafe extern "C" fn sp_bitvec_load( data: *const u8, data_length: usize, ) -> *mut SPBitVec { @@ -101,9 +101,9 @@ pub unsafe extern "C" fn sp_bit_vec_load( /// - `bit_vec` points to a valid [SPBitVec] /// - `bit_vec` is not written to concurrently /// - the returned instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_bit_vec_free`. +/// by explicitly calling `sp_bitvec_free`. #[no_mangle] -pub unsafe extern "C" fn sp_bit_vec_clone( +pub unsafe extern "C" fn sp_bitvec_clone( bit_vec: *const SPBitVec, ) -> *mut SPBitVec { assert!(!bit_vec.is_null()); @@ -126,7 +126,7 @@ pub unsafe extern "C" fn sp_bit_vec_clone( /// - `bit_vec` is not used concurrently or after this call /// - `bit_vec` was not passed to another consuming function, e.g. to create a [SPCommand] #[no_mangle] -pub unsafe extern "C" fn sp_bit_vec_free(bit_vec: *mut SPBitVec) { +pub unsafe extern "C" fn sp_bitvec_free(bit_vec: *mut SPBitVec) { assert!(!bit_vec.is_null()); _ = Box::from_raw(bit_vec); } @@ -152,7 +152,7 @@ pub unsafe extern "C" fn sp_bit_vec_free(bit_vec: *mut SPBitVec) { /// - `bit_vec` points to a valid [SPBitVec] /// - `bit_vec` is not written to concurrently #[no_mangle] -pub unsafe extern "C" fn sp_bit_vec_get( +pub unsafe extern "C" fn sp_bitvec_get( bit_vec: *const SPBitVec, index: usize, ) -> bool { @@ -180,7 +180,7 @@ pub unsafe extern "C" fn sp_bit_vec_get( /// - `bit_vec` points to a valid [SPBitVec] /// - `bit_vec` is not written to or read from concurrently #[no_mangle] -pub unsafe extern "C" fn sp_bit_vec_set( +pub unsafe extern "C" fn sp_bitvec_set( bit_vec: *mut SPBitVec, index: usize, value: bool, @@ -207,7 +207,7 @@ pub unsafe extern "C" fn sp_bit_vec_set( /// - `bit_vec` points to a valid [SPBitVec] /// - `bit_vec` is not written to or read from concurrently #[no_mangle] -pub unsafe extern "C" fn sp_bit_vec_fill(bit_vec: *mut SPBitVec, value: bool) { +pub unsafe extern "C" fn sp_bitvec_fill(bit_vec: *mut SPBitVec, value: bool) { assert!(!bit_vec.is_null()); (*bit_vec).0.fill(value) } @@ -228,7 +228,7 @@ pub unsafe extern "C" fn sp_bit_vec_fill(bit_vec: *mut SPBitVec, value: bool) { /// /// - `bit_vec` points to a valid [SPBitVec] #[no_mangle] -pub unsafe extern "C" fn sp_bit_vec_len(bit_vec: *const SPBitVec) -> usize { +pub unsafe extern "C" fn sp_bitvec_len(bit_vec: *const SPBitVec) -> usize { assert!(!bit_vec.is_null()); (*bit_vec).0.len() } @@ -249,7 +249,7 @@ pub unsafe extern "C" fn sp_bit_vec_len(bit_vec: *const SPBitVec) -> usize { /// /// - `bit_vec` points to a valid [SPBitVec] #[no_mangle] -pub unsafe extern "C" fn sp_bit_vec_is_empty(bit_vec: *const SPBitVec) -> bool { +pub unsafe extern "C" fn sp_bitvec_is_empty(bit_vec: *const SPBitVec) -> bool { assert!(!bit_vec.is_null()); (*bit_vec).0.is_empty() } @@ -272,7 +272,7 @@ pub unsafe extern "C" fn sp_bit_vec_is_empty(bit_vec: *const SPBitVec) -> bool { /// - the returned memory range is never accessed after the passed [SPBitVec] has been freed /// - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly #[no_mangle] -pub unsafe extern "C" fn sp_bit_vec_unsafe_data_ref( +pub unsafe extern "C" fn sp_bitvec_unsafe_data_ref( bit_vec: *mut SPBitVec, ) -> SPByteSlice { assert!(!bit_vec.is_null()); diff --git a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs b/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs index df0873f..1dd15a7 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs @@ -37,10 +37,10 @@ namespace ServicePoint.BindGen /// 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_bit_vec_free`. + /// by explicitly calling `sp_bitvec_free`. /// - [DllImport(__DllName, EntryPoint = "sp_bit_vec_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BitVec* sp_bit_vec_new(nuint size); + [DllImport(__DllName, EntryPoint = "sp_bitvec_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern BitVec* sp_bitvec_new(nuint size); /// /// Interpret the data as a series of bits and load then into a new [SPBitVec] instance. @@ -58,10 +58,10 @@ namespace ServicePoint.BindGen /// - `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_bit_vec_free`. + /// by explicitly calling `sp_bitvec_free`. /// - [DllImport(__DllName, EntryPoint = "sp_bit_vec_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BitVec* sp_bit_vec_load(byte* data, nuint data_length); + [DllImport(__DllName, EntryPoint = "sp_bitvec_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern BitVec* sp_bitvec_load(byte* data, nuint data_length); /// /// Clones a [SPBitVec]. @@ -79,10 +79,10 @@ namespace ServicePoint.BindGen /// - `bit_vec` points to a valid [SPBitVec] /// - `bit_vec` is not written to concurrently /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_bit_vec_free`. + /// by explicitly calling `sp_bitvec_free`. /// - [DllImport(__DllName, EntryPoint = "sp_bit_vec_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BitVec* sp_bit_vec_clone(BitVec* bit_vec); + [DllImport(__DllName, EntryPoint = "sp_bitvec_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern BitVec* sp_bitvec_clone(BitVec* bit_vec); /// /// Deallocates a [SPBitVec]. @@ -99,8 +99,8 @@ namespace ServicePoint.BindGen /// - `bit_vec` is not used concurrently or after this call /// - `bit_vec` was not passed to another consuming function, e.g. to create a [SPCommand] /// - [DllImport(__DllName, EntryPoint = "sp_bit_vec_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bit_vec_free(BitVec* bit_vec); + [DllImport(__DllName, EntryPoint = "sp_bitvec_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bitvec_free(BitVec* bit_vec); /// /// Gets the value of a bit from the [SPBitVec]. @@ -124,9 +124,9 @@ namespace ServicePoint.BindGen /// - `bit_vec` points to a valid [SPBitVec] /// - `bit_vec` is not written to concurrently /// - [DllImport(__DllName, EntryPoint = "sp_bit_vec_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + [DllImport(__DllName, EntryPoint = "sp_bitvec_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_bit_vec_get(BitVec* bit_vec, nuint index); + public static extern bool sp_bitvec_get(BitVec* bit_vec, nuint index); /// /// Sets the value of a bit in the [SPBitVec]. @@ -149,8 +149,8 @@ namespace ServicePoint.BindGen /// - `bit_vec` points to a valid [SPBitVec] /// - `bit_vec` is not written to or read from concurrently /// - [DllImport(__DllName, EntryPoint = "sp_bit_vec_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bit_vec_set(BitVec* bit_vec, nuint index, [MarshalAs(UnmanagedType.U1)] bool value); + [DllImport(__DllName, EntryPoint = "sp_bitvec_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bitvec_set(BitVec* bit_vec, nuint index, [MarshalAs(UnmanagedType.U1)] bool value); /// /// Sets the value of all bits in the [SPBitVec]. @@ -171,8 +171,8 @@ namespace ServicePoint.BindGen /// - `bit_vec` points to a valid [SPBitVec] /// - `bit_vec` is not written to or read from concurrently /// - [DllImport(__DllName, EntryPoint = "sp_bit_vec_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bit_vec_fill(BitVec* bit_vec, [MarshalAs(UnmanagedType.U1)] bool value); + [DllImport(__DllName, EntryPoint = "sp_bitvec_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bitvec_fill(BitVec* bit_vec, [MarshalAs(UnmanagedType.U1)] bool value); /// /// Gets the length of the [SPBitVec] in bits. @@ -191,8 +191,8 @@ namespace ServicePoint.BindGen /// /// - `bit_vec` points to a valid [SPBitVec] /// - [DllImport(__DllName, EntryPoint = "sp_bit_vec_len", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_bit_vec_len(BitVec* bit_vec); + [DllImport(__DllName, EntryPoint = "sp_bitvec_len", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern nuint sp_bitvec_len(BitVec* bit_vec); /// /// Returns true if length is 0. @@ -211,9 +211,9 @@ namespace ServicePoint.BindGen /// /// - `bit_vec` points to a valid [SPBitVec] /// - [DllImport(__DllName, EntryPoint = "sp_bit_vec_is_empty", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + [DllImport(__DllName, EntryPoint = "sp_bitvec_is_empty", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_bit_vec_is_empty(BitVec* bit_vec); + public static extern bool sp_bitvec_is_empty(BitVec* bit_vec); /// /// Gets an unsafe reference to the data of the [SPBitVec] instance. @@ -234,8 +234,8 @@ namespace ServicePoint.BindGen /// - the returned memory range is never accessed after the passed [SPBitVec] has been freed /// - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly /// - [DllImport(__DllName, EntryPoint = "sp_bit_vec_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteSlice sp_bit_vec_unsafe_data_ref(BitVec* bit_vec); + [DllImport(__DllName, EntryPoint = "sp_bitvec_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern ByteSlice sp_bitvec_unsafe_data_ref(BitVec* bit_vec); /// /// Creates a new [SPBrightnessGrid] with the specified dimensions. diff --git a/crates/servicepoint_binding_cs/ServicePoint/BitVec.cs b/crates/servicepoint_binding_cs/ServicePoint/BitVec.cs index 2abe78c..ab697e0 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BitVec.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/BitVec.cs @@ -8,7 +8,7 @@ public sealed class BitVec : SpNativeInstance { unsafe { - return new BitVec(NativeMethods.sp_bit_vec_new((nuint)size)); + return new BitVec(NativeMethods.sp_bitvec_new((nuint)size)); } } @@ -18,7 +18,7 @@ public sealed class BitVec : SpNativeInstance { fixed (byte* bytesPtr = bytes) { - return new BitVec(NativeMethods.sp_bit_vec_load(bytesPtr, (nuint)bytes.Length)); + return new BitVec(NativeMethods.sp_bitvec_load(bytesPtr, (nuint)bytes.Length)); } } } @@ -27,7 +27,7 @@ public sealed class BitVec : SpNativeInstance { unsafe { - return new BitVec(NativeMethods.sp_bit_vec_clone(Instance)); + return new BitVec(NativeMethods.sp_bitvec_clone(Instance)); } } @@ -37,14 +37,14 @@ public sealed class BitVec : SpNativeInstance { unsafe { - return NativeMethods.sp_bit_vec_get(Instance, (nuint)index); + return NativeMethods.sp_bitvec_get(Instance, (nuint)index); } } set { unsafe { - NativeMethods.sp_bit_vec_set(Instance, (nuint)index, value); + NativeMethods.sp_bitvec_set(Instance, (nuint)index, value); } } } @@ -53,7 +53,7 @@ public sealed class BitVec : SpNativeInstance { unsafe { - NativeMethods.sp_bit_vec_fill(Instance, value); + NativeMethods.sp_bitvec_fill(Instance, value); } } @@ -63,7 +63,7 @@ public sealed class BitVec : SpNativeInstance { unsafe { - return (int)NativeMethods.sp_bit_vec_len(Instance); + return (int)NativeMethods.sp_bitvec_len(Instance); } } } @@ -74,7 +74,7 @@ public sealed class BitVec : SpNativeInstance { unsafe { - var slice = NativeMethods.sp_bit_vec_unsafe_data_ref(Instance); + var slice = NativeMethods.sp_bitvec_unsafe_data_ref(Instance); return new Span(slice.start, (int)slice.length); } } @@ -84,5 +84,5 @@ public sealed class BitVec : SpNativeInstance { } - private protected override unsafe void Free() => NativeMethods.sp_bit_vec_free(Instance); + private protected override unsafe void Free() => NativeMethods.sp_bitvec_free(Instance); } From c6450d77593f0e196130e06a48304be74b9847d3 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Tue, 15 Oct 2024 21:51:22 +0200 Subject: [PATCH 19/27] rename sp_bit_vec_* to sp_bitvec_* --- .../examples/lang_c/include/servicepoint.h | 414 +++++------ .../src/{bit_vec.rs => bitvec.rs} | 0 crates/servicepoint_binding_c/src/lib.rs | 4 +- .../ServicePoint/BindGen/ServicePoint.g.cs | 672 +++++++++--------- 4 files changed, 545 insertions(+), 545 deletions(-) rename crates/servicepoint_binding_c/src/{bit_vec.rs => bitvec.rs} (100%) diff --git a/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h b/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h index e85a9fa..617cdeb 100644 --- a/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h +++ b/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h @@ -196,213 +196,6 @@ typedef struct SPByteSlice { extern "C" { #endif // __cplusplus -/** - * Clones a [SPBitVec]. - * - * returns: new [SPBitVec] instance. Will never return NULL. - * - * # Panics - * - * - when `bit_vec` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid [SPBitVec] - * - `bit_vec` is not written to concurrently - * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_bitvec_free`. - */ -struct SPBitVec *sp_bitvec_clone(const struct SPBitVec *bit_vec); - -/** - * Sets the value of all bits in the [SPBitVec]. - * - * # Arguments - * - * - `bit_vec`: instance to write to - * - `value`: the value to set all bits to - * - * # Panics - * - * - when `bit_vec` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid [SPBitVec] - * - `bit_vec` is not written to or read from concurrently - */ -void sp_bitvec_fill(struct SPBitVec *bit_vec, bool value); - -/** - * Deallocates a [SPBitVec]. - * - * # Panics - * - * - when `but_vec` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid [SPBitVec] - * - `bit_vec` is not used concurrently or after this call - * - `bit_vec` was not passed to another consuming function, e.g. to create a [SPCommand] - */ -void sp_bitvec_free(struct SPBitVec *bit_vec); - -/** - * Gets the value of a bit from the [SPBitVec]. - * - * # Arguments - * - * - `bit_vec`: instance to read from - * - `index`: the bit index to read - * - * returns: value of the bit - * - * # Panics - * - * - when `bit_vec` is NULL - * - when accessing `index` out of bounds - * - * # Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid [SPBitVec] - * - `bit_vec` is not written to concurrently - */ -bool sp_bitvec_get(const struct SPBitVec *bit_vec, size_t index); - -/** - * Returns true if length is 0. - * - * # Arguments - * - * - `bit_vec`: instance to write to - * - * # Panics - * - * - when `bit_vec` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid [SPBitVec] - */ -bool sp_bitvec_is_empty(const struct SPBitVec *bit_vec); - -/** - * Gets the length of the [SPBitVec] in bits. - * - * # Arguments - * - * - `bit_vec`: instance to write to - * - * # Panics - * - * - when `bit_vec` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid [SPBitVec] - */ -size_t sp_bitvec_len(const struct SPBitVec *bit_vec); - -/** - * Interpret the data as a series of bits and load then into a new [SPBitVec] instance. - * - * returns: [SPBitVec] instance containing data. Will never return NULL. - * - * # Panics - * - * - when `data` is NULL - * - * # 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_bitvec_free`. - */ -struct SPBitVec *sp_bitvec_load(const uint8_t *data, - size_t data_length); - -/** - * Creates a new [SPBitVec] instance. - * - * # Arguments - * - * - `size`: size in bits. - * - * returns: [SPBitVec] with all bits set to false. Will never return NULL. - * - * # Panics - * - * - when `size` is not divisible by 8. - * - * # 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_bitvec_free`. - */ -struct SPBitVec *sp_bitvec_new(size_t size); - -/** - * Sets the value of a bit in the [SPBitVec]. - * - * # Arguments - * - * - `bit_vec`: instance to write to - * - `index`: the bit index to edit - * - `value`: the value to set the bit to - * - * # Panics - * - * - when `bit_vec` is NULL - * - when accessing `index` out of bounds - * - * # Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid [SPBitVec] - * - `bit_vec` is not written to or read from concurrently - */ -void sp_bitvec_set(struct SPBitVec *bit_vec, size_t index, bool value); - -/** - * Gets an unsafe reference to the data of the [SPBitVec] instance. - * - * # Arguments - * - * - `bit_vec`: instance to write to - * - * # Panics - * - * - when `bit_vec` is NULL - * - * ## Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid [SPBitVec] - * - the returned memory range is never accessed after the passed [SPBitVec] has been freed - * - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly - */ -struct SPByteSlice sp_bitvec_unsafe_data_ref(struct SPBitVec *bit_vec); - /** * Clones a [SPBitmap]. * @@ -616,6 +409,213 @@ struct SPByteSlice sp_bitmap_unsafe_data_ref(struct SPBitmap *bitmap); */ size_t sp_bitmap_width(const struct SPBitmap *bitmap); +/** + * Clones a [SPBitVec]. + * + * returns: new [SPBitVec] instance. Will never return NULL. + * + * # Panics + * + * - when `bit_vec` is NULL + * + * # Safety + * + * The caller has to make sure that: + * + * - `bit_vec` points to a valid [SPBitVec] + * - `bit_vec` is not written to concurrently + * - the returned instance is freed in some way, either by using a consuming function or + * by explicitly calling `sp_bitvec_free`. + */ +struct SPBitVec *sp_bitvec_clone(const struct SPBitVec *bit_vec); + +/** + * Sets the value of all bits in the [SPBitVec]. + * + * # Arguments + * + * - `bit_vec`: instance to write to + * - `value`: the value to set all bits to + * + * # Panics + * + * - when `bit_vec` is NULL + * + * # Safety + * + * The caller has to make sure that: + * + * - `bit_vec` points to a valid [SPBitVec] + * - `bit_vec` is not written to or read from concurrently + */ +void sp_bitvec_fill(struct SPBitVec *bit_vec, bool value); + +/** + * Deallocates a [SPBitVec]. + * + * # Panics + * + * - when `but_vec` is NULL + * + * # Safety + * + * The caller has to make sure that: + * + * - `bit_vec` points to a valid [SPBitVec] + * - `bit_vec` is not used concurrently or after this call + * - `bit_vec` was not passed to another consuming function, e.g. to create a [SPCommand] + */ +void sp_bitvec_free(struct SPBitVec *bit_vec); + +/** + * Gets the value of a bit from the [SPBitVec]. + * + * # Arguments + * + * - `bit_vec`: instance to read from + * - `index`: the bit index to read + * + * returns: value of the bit + * + * # Panics + * + * - when `bit_vec` is NULL + * - when accessing `index` out of bounds + * + * # Safety + * + * The caller has to make sure that: + * + * - `bit_vec` points to a valid [SPBitVec] + * - `bit_vec` is not written to concurrently + */ +bool sp_bitvec_get(const struct SPBitVec *bit_vec, size_t index); + +/** + * Returns true if length is 0. + * + * # Arguments + * + * - `bit_vec`: instance to write to + * + * # Panics + * + * - when `bit_vec` is NULL + * + * # Safety + * + * The caller has to make sure that: + * + * - `bit_vec` points to a valid [SPBitVec] + */ +bool sp_bitvec_is_empty(const struct SPBitVec *bit_vec); + +/** + * Gets the length of the [SPBitVec] in bits. + * + * # Arguments + * + * - `bit_vec`: instance to write to + * + * # Panics + * + * - when `bit_vec` is NULL + * + * # Safety + * + * The caller has to make sure that: + * + * - `bit_vec` points to a valid [SPBitVec] + */ +size_t sp_bitvec_len(const struct SPBitVec *bit_vec); + +/** + * Interpret the data as a series of bits and load then into a new [SPBitVec] instance. + * + * returns: [SPBitVec] instance containing data. Will never return NULL. + * + * # Panics + * + * - when `data` is NULL + * + * # 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_bitvec_free`. + */ +struct SPBitVec *sp_bitvec_load(const uint8_t *data, + size_t data_length); + +/** + * Creates a new [SPBitVec] instance. + * + * # Arguments + * + * - `size`: size in bits. + * + * returns: [SPBitVec] with all bits set to false. Will never return NULL. + * + * # Panics + * + * - when `size` is not divisible by 8. + * + * # 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_bitvec_free`. + */ +struct SPBitVec *sp_bitvec_new(size_t size); + +/** + * Sets the value of a bit in the [SPBitVec]. + * + * # Arguments + * + * - `bit_vec`: instance to write to + * - `index`: the bit index to edit + * - `value`: the value to set the bit to + * + * # Panics + * + * - when `bit_vec` is NULL + * - when accessing `index` out of bounds + * + * # Safety + * + * The caller has to make sure that: + * + * - `bit_vec` points to a valid [SPBitVec] + * - `bit_vec` is not written to or read from concurrently + */ +void sp_bitvec_set(struct SPBitVec *bit_vec, size_t index, bool value); + +/** + * Gets an unsafe reference to the data of the [SPBitVec] instance. + * + * # Arguments + * + * - `bit_vec`: instance to write to + * + * # Panics + * + * - when `bit_vec` is NULL + * + * ## Safety + * + * The caller has to make sure that: + * + * - `bit_vec` points to a valid [SPBitVec] + * - the returned memory range is never accessed after the passed [SPBitVec] has been freed + * - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly + */ +struct SPByteSlice sp_bitvec_unsafe_data_ref(struct SPBitVec *bit_vec); + /** * Clones a [SPBrightnessGrid]. * diff --git a/crates/servicepoint_binding_c/src/bit_vec.rs b/crates/servicepoint_binding_c/src/bitvec.rs similarity index 100% rename from crates/servicepoint_binding_c/src/bit_vec.rs rename to crates/servicepoint_binding_c/src/bitvec.rs diff --git a/crates/servicepoint_binding_c/src/lib.rs b/crates/servicepoint_binding_c/src/lib.rs index 2c9006d..0e0ddd0 100644 --- a/crates/servicepoint_binding_c/src/lib.rs +++ b/crates/servicepoint_binding_c/src/lib.rs @@ -25,7 +25,7 @@ //! } //! ``` -pub use crate::bit_vec::*; +pub use crate::bitvec::*; pub use crate::bitmap::*; pub use crate::brightness_grid::*; pub use crate::byte_slice::*; @@ -35,7 +35,7 @@ pub use crate::constants::*; pub use crate::cp437_grid::*; pub use crate::packet::*; -mod bit_vec; +mod bitvec; mod bitmap; mod brightness_grid; mod byte_slice; diff --git a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs b/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs index 1dd15a7..abd6fd5 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs @@ -237,6 +237,171 @@ namespace ServicePoint.BindGen [DllImport(__DllName, EntryPoint = "sp_bitvec_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern ByteSlice sp_bitvec_unsafe_data_ref(BitVec* bit_vec); + /// + /// Creates a new instance of [SPConnection]. + /// + /// returns: NULL if connection fails, or connected instance + /// + /// # Panics + /// + /// - when `host` is null or an invalid host + /// + /// # 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_connection_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_connection_open", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Connection* sp_connection_open(byte* host); + + /// + /// Sends a [SPPacket] to the display using the [SPConnection]. + /// + /// The passed `packet` gets consumed. + /// + /// returns: true in case of success + /// + /// # Panics + /// + /// - when `connection` is NULL + /// - when `packet` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `connection` points to a valid instance of [SPConnection] + /// - `packet` points to a valid instance of [SPPacket] + /// - `packet` is not used concurrently or after this call + /// + [DllImport(__DllName, EntryPoint = "sp_connection_send_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.U1)] + public static extern bool sp_connection_send_packet(Connection* connection, Packet* packet); + + /// + /// Sends a [SPCommand] to the display using the [SPConnection]. + /// + /// The passed `command` gets consumed. + /// + /// returns: true in case of success + /// + /// # Panics + /// + /// - when `connection` is NULL + /// - when `command` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `connection` points to a valid instance of [SPConnection] + /// - `command` points to a valid instance of [SPPacket] + /// - `command` is not used concurrently or after this call + /// + [DllImport(__DllName, EntryPoint = "sp_connection_send_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.U1)] + public static extern bool sp_connection_send_command(Connection* connection, Command* command); + + /// + /// Closes and deallocates a [SPConnection]. + /// + /// # Panics + /// + /// - when `connection` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `connection` points to a valid [SPConnection] + /// - `connection` is not used concurrently or after this call + /// + [DllImport(__DllName, EntryPoint = "sp_connection_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_connection_free(Connection* connection); + + /// + /// Turns a [SPCommand] into a [SPPacket]. + /// The [SPCommand] gets consumed. + /// + /// Will never return NULL. + /// + /// # Panics + /// + /// - when `command` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - [SPCommand] points to a valid instance of [SPCommand] + /// - [SPCommand] is not used concurrently or after this call + /// - the returned [SPPacket] instance is freed in some way, either by using a consuming function or + /// by explicitly calling `sp_packet_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_packet_from_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Packet* sp_packet_from_command(Command* command); + + /// + /// Tries to load a [SPPacket] from the passed array with the specified length. + /// + /// returns: NULL in case of an error, pointer to the allocated packet otherwise + /// + /// # Panics + /// + /// - when `data` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `data` points to a valid memory region of at least `length` bytes + /// - `data` is not written to concurrently + /// - the returned [SPPacket] instance is freed in some way, either by using a consuming function or + /// by explicitly calling `sp_packet_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_packet_try_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Packet* sp_packet_try_load(byte* data, nuint length); + + /// + /// Clones a [SPPacket]. + /// + /// Will never return NULL. + /// + /// # Panics + /// + /// - when `packet` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `packet` points to a valid [SPPacket] + /// - `packet` is not written to concurrently + /// - the returned instance is freed in some way, either by using a consuming function or + /// by explicitly calling `sp_packet_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_packet_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Packet* sp_packet_clone(Packet* packet); + + /// + /// Deallocates a [SPPacket]. + /// + /// # Panics + /// + /// - when `sp_packet_free` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `packet` points to a valid [SPPacket] + /// - `packet` is not used concurrently or after this call + /// + [DllImport(__DllName, EntryPoint = "sp_packet_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_packet_free(Packet* packet); + /// /// Creates a new [SPBrightnessGrid] with the specified dimensions. /// @@ -465,194 +630,125 @@ namespace ServicePoint.BindGen public static extern ByteSlice sp_brightness_grid_unsafe_data_ref(BrightnessGrid* brightness_grid); /// - /// Creates a new instance of [SPConnection]. + /// Creates a new [SPBitmap] with the specified dimensions. /// - /// returns: NULL if connection fails, or connected instance + /// # Arguments + /// + /// - `width`: size in pixels in x-direction + /// - `height`: size in pixels in y-direction + /// + /// returns: [SPBitmap] initialized to all pixels off. Will never return NULL. /// /// # Panics /// - /// - when `host` is null or an invalid host + /// - when the width is not dividable by 8 /// /// # 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_connection_free`. + /// by explicitly calling `sp_bitmap_free`. /// - [DllImport(__DllName, EntryPoint = "sp_connection_open", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Connection* sp_connection_open(byte* host); + [DllImport(__DllName, EntryPoint = "sp_bitmap_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Bitmap* sp_bitmap_new(nuint width, nuint height); /// - /// Sends a [SPPacket] to the display using the [SPConnection]. + /// Loads a [SPBitmap] with the specified dimensions from the provided data. /// - /// The passed `packet` gets consumed. + /// # Arguments /// - /// returns: true in case of success + /// - `width`: size in pixels in x-direction + /// - `height`: size in pixels in y-direction /// - /// # Panics - /// - /// - when `connection` is NULL - /// - when `packet` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `connection` points to a valid instance of [SPConnection] - /// - `packet` points to a valid instance of [SPPacket] - /// - `packet` is not used concurrently or after this call - /// - [DllImport(__DllName, EntryPoint = "sp_connection_send_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_connection_send_packet(Connection* connection, Packet* packet); - - /// - /// Sends a [SPCommand] to the display using the [SPConnection]. - /// - /// The passed `command` gets consumed. - /// - /// returns: true in case of success - /// - /// # Panics - /// - /// - when `connection` is NULL - /// - when `command` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `connection` points to a valid instance of [SPConnection] - /// - `command` points to a valid instance of [SPPacket] - /// - `command` is not used concurrently or after this call - /// - [DllImport(__DllName, EntryPoint = "sp_connection_send_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_connection_send_command(Connection* connection, Command* command); - - /// - /// Closes and deallocates a [SPConnection]. - /// - /// # Panics - /// - /// - when `connection` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `connection` points to a valid [SPConnection] - /// - `connection` is not used concurrently or after this call - /// - [DllImport(__DllName, EntryPoint = "sp_connection_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_connection_free(Connection* connection); - - /// - /// Creates a new [SPCp437Grid] with the specified dimensions. - /// - /// returns: [SPCp437Grid] initialized to 0. Will never return NULL. - /// - /// # 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_cp437_grid_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Cp437Grid* sp_cp437_grid_new(nuint width, nuint height); - - /// - /// Loads a [SPCp437Grid] with the specified dimensions from the provided data. - /// - /// Will never return NULL. + /// returns: [SPBitmap] that contains a copy of the provided data. Will never return NULL. /// /// # Panics /// /// - when `data` is NULL - /// - when the provided `data_length` does not match `height` and `width` + /// - when the dimensions and data size do not match exactly. + /// - when the width is not dividable by 8 /// /// # Safety /// /// The caller has to make sure that: /// - /// - `data` points to a valid memory location of at least `data_length` - /// bytes in size. + /// - `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_cp437_grid_free`. + /// by explicitly calling `sp_bitmap_free`. /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Cp437Grid* sp_cp437_grid_load(nuint width, nuint height, byte* data, nuint data_length); + [DllImport(__DllName, EntryPoint = "sp_bitmap_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Bitmap* sp_bitmap_load(nuint width, nuint height, byte* data, nuint data_length); /// - /// Clones a [SPCp437Grid]. + /// Clones a [SPBitmap]. /// /// Will never return NULL. /// /// # Panics /// - /// - when `cp437_grid` is NULL + /// - when `bitmap` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `cp437_grid` points to a valid [SPCp437Grid] - /// - `cp437_grid` is not written to concurrently + /// - `bitmap` points to a valid [SPBitmap] + /// - `bitmap` is not written to concurrently /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_cp437_grid_free`. + /// by explicitly calling `sp_bitmap_free`. /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Cp437Grid* sp_cp437_grid_clone(Cp437Grid* cp437_grid); + [DllImport(__DllName, EntryPoint = "sp_bitmap_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Bitmap* sp_bitmap_clone(Bitmap* bitmap); /// - /// Deallocates a [SPCp437Grid]. + /// Deallocates a [SPBitmap]. /// /// # Panics /// - /// - when `cp437_grid` is NULL + /// - when `bitmap` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `cp437_grid` points to a valid [SPCp437Grid] - /// - `cp437_grid` is not used concurrently or after cp437_grid call - /// - `cp437_grid` was not passed to another consuming function, e.g. to create a [SPCommand] + /// - `bitmap` points to a valid [SPBitmap] + /// - `bitmap` is not used concurrently or after bitmap call + /// - `bitmap` was not passed to another consuming function, e.g. to create a [SPCommand] /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_cp437_grid_free(Cp437Grid* cp437_grid); + [DllImport(__DllName, EntryPoint = "sp_bitmap_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bitmap_free(Bitmap* bitmap); /// - /// Gets the current value at the specified position. + /// Gets the current value at the specified position in the [SPBitmap]. /// /// # Arguments /// - /// - `cp437_grid`: instance to read from + /// - `bitmap`: instance to read from /// - `x` and `y`: position of the cell to read /// /// # Panics /// - /// - when `cp437_grid` is NULL + /// - when `bitmap` is NULL /// - when accessing `x` or `y` out of bounds /// /// # Safety /// /// The caller has to make sure that: /// - /// - `cp437_grid` points to a valid [SPCp437Grid] - /// - `cp437_grid` is not written to concurrently + /// - `bitmap` points to a valid [SPBitmap] + /// - `bitmap` is not written to concurrently /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern byte sp_cp437_grid_get(Cp437Grid* cp437_grid, nuint x, nuint y); + [DllImport(__DllName, EntryPoint = "sp_bitmap_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.U1)] + public static extern bool sp_bitmap_get(Bitmap* bitmap, nuint x, nuint y); /// - /// Sets the value of the specified position in the [SPCp437Grid]. + /// Sets the value of the specified position in the [SPBitmap]. /// /// # Arguments /// - /// - `cp437_grid`: instance to write to + /// - `bitmap`: instance to write to /// - `x` and `y`: position of the cell /// - `value`: the value to write to the cell /// @@ -660,181 +756,98 @@ namespace ServicePoint.BindGen /// /// # Panics /// - /// - when `cp437_grid` is NULL + /// - when `bitmap` is NULL /// - when accessing `x` or `y` out of bounds /// /// # Safety /// /// The caller has to make sure that: /// - /// - `cp437_grid` points to a valid [SPBitVec] - /// - `cp437_grid` is not written to or read from concurrently + /// - `bitmap` points to a valid [SPBitmap] + /// - `bitmap` is not written to or read from concurrently /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_cp437_grid_set(Cp437Grid* cp437_grid, nuint x, nuint y, byte value); + [DllImport(__DllName, EntryPoint = "sp_bitmap_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bitmap_set(Bitmap* bitmap, nuint x, nuint y, [MarshalAs(UnmanagedType.U1)] bool value); /// - /// Sets the value of all cells in the [SPCp437Grid]. + /// Sets the state of all pixels in the [SPBitmap]. /// /// # Arguments /// - /// - `cp437_grid`: instance to write to - /// - `value`: the value to set all cells to + /// - `bitmap`: instance to write to + /// - `value`: the value to set all pixels to /// /// # Panics /// - /// - when `cp437_grid` is NULL + /// - when `bitmap` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `cp437_grid` points to a valid [SPCp437Grid] - /// - `cp437_grid` is not written to or read from concurrently + /// - `bitmap` points to a valid [SPBitmap] + /// - `bitmap` is not written to or read from concurrently /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_cp437_grid_fill(Cp437Grid* cp437_grid, byte value); + [DllImport(__DllName, EntryPoint = "sp_bitmap_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bitmap_fill(Bitmap* bitmap, [MarshalAs(UnmanagedType.U1)] bool value); /// - /// Gets the width of the [SPCp437Grid] instance. + /// Gets the width in pixels of the [SPBitmap] instance. /// /// # Arguments /// - /// - `cp437_grid`: instance to read from + /// - `bitmap`: instance to read from /// /// # Panics /// - /// - when `cp437_grid` is NULL + /// - when `bitmap` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `cp437_grid` points to a valid [SPCp437Grid] + /// - `bitmap` points to a valid [SPBitmap] /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_cp437_grid_width(Cp437Grid* cp437_grid); + [DllImport(__DllName, EntryPoint = "sp_bitmap_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern nuint sp_bitmap_width(Bitmap* bitmap); /// - /// Gets the height of the [SPCp437Grid] instance. + /// Gets the height in pixels of the [SPBitmap] instance. /// /// # Arguments /// - /// - `cp437_grid`: instance to read from + /// - `bitmap`: instance to read from /// /// # Panics /// - /// - when `cp437_grid` is NULL + /// - when `bitmap` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `cp437_grid` points to a valid [SPCp437Grid] + /// - `bitmap` points to a valid [SPBitmap] /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_cp437_grid_height(Cp437Grid* cp437_grid); + [DllImport(__DllName, EntryPoint = "sp_bitmap_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern nuint sp_bitmap_height(Bitmap* bitmap); /// - /// Gets an unsafe reference to the data of the [SPCp437Grid] instance. - /// - /// Will never return NULL. + /// Gets an unsafe reference to the data of the [SPBitmap] instance. /// /// # Panics /// - /// - when `cp437_grid` is NULL - /// - /// ## Safety - /// - /// The caller has to make sure that: - /// - /// - `cp437_grid` points to a valid [SPCp437Grid] - /// - the returned memory range is never accessed after the passed [SPCp437Grid] has been freed - /// - the returned memory range is never accessed concurrently, either via the [SPCp437Grid] or directly - /// - [DllImport(__DllName, EntryPoint = "sp_cp437_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteSlice sp_cp437_grid_unsafe_data_ref(Cp437Grid* cp437_grid); - - /// - /// Turns a [SPCommand] into a [SPPacket]. - /// The [SPCommand] gets consumed. - /// - /// Will never return NULL. - /// - /// # Panics - /// - /// - when `command` is NULL + /// - when `bitmap` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - [SPCommand] points to a valid instance of [SPCommand] - /// - [SPCommand] is not used concurrently or after this call - /// - the returned [SPPacket] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_packet_free`. + /// - `bitmap` points to a valid [SPBitmap] + /// - the returned memory range is never accessed after the passed [SPBitmap] has been freed + /// - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly /// - [DllImport(__DllName, EntryPoint = "sp_packet_from_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Packet* sp_packet_from_command(Command* command); - - /// - /// Tries to load a [SPPacket] from the passed array with the specified length. - /// - /// returns: NULL in case of an error, pointer to the allocated packet otherwise - /// - /// # Panics - /// - /// - when `data` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `data` points to a valid memory region of at least `length` bytes - /// - `data` is not written to concurrently - /// - the returned [SPPacket] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_packet_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_packet_try_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Packet* sp_packet_try_load(byte* data, nuint length); - - /// - /// Clones a [SPPacket]. - /// - /// Will never return NULL. - /// - /// # Panics - /// - /// - when `packet` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `packet` points to a valid [SPPacket] - /// - `packet` is not written to concurrently - /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_packet_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_packet_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Packet* sp_packet_clone(Packet* packet); - - /// - /// Deallocates a [SPPacket]. - /// - /// # Panics - /// - /// - when `sp_packet_free` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `packet` points to a valid [SPPacket] - /// - `packet` is not used concurrently or after this call - /// - [DllImport(__DllName, EntryPoint = "sp_packet_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_packet_free(Packet* packet); + [DllImport(__DllName, EntryPoint = "sp_bitmap_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern ByteSlice sp_bitmap_unsafe_data_ref(Bitmap* bitmap); /// /// Tries to turn a [SPPacket] into a [SPCommand]. @@ -1172,125 +1185,110 @@ namespace ServicePoint.BindGen public static extern void sp_command_free(Command* command); /// - /// Creates a new [SPBitmap] with the specified dimensions. + /// Creates a new [SPCp437Grid] with the specified dimensions. /// - /// # Arguments - /// - /// - `width`: size in pixels in x-direction - /// - `height`: size in pixels in y-direction - /// - /// returns: [SPBitmap] initialized to all pixels off. Will never return NULL. - /// - /// # Panics - /// - /// - when the width is not dividable by 8 + /// returns: [SPCp437Grid] initialized to 0. Will never return NULL. /// /// # 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_bitmap_free`. + /// by explicitly calling `sp_cp437_grid_free`. /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Bitmap* sp_bitmap_new(nuint width, nuint height); + [DllImport(__DllName, EntryPoint = "sp_cp437_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Cp437Grid* sp_cp437_grid_new(nuint width, nuint height); /// - /// Loads a [SPBitmap] with the specified dimensions from the provided data. - /// - /// # Arguments - /// - /// - `width`: size in pixels in x-direction - /// - `height`: size in pixels in y-direction - /// - /// returns: [SPBitmap] that contains a copy of the provided data. Will never return NULL. - /// - /// # Panics - /// - /// - when `data` is NULL - /// - when the dimensions and data size do not match exactly. - /// - when the width is not dividable by 8 - /// - /// # 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_bitmap_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Bitmap* sp_bitmap_load(nuint width, nuint height, byte* data, nuint data_length); - - /// - /// Clones a [SPBitmap]. + /// Loads a [SPCp437Grid] with the specified dimensions from the provided data. /// /// Will never return NULL. /// /// # Panics /// - /// - when `bitmap` is NULL + /// - when `data` is NULL + /// - when the provided `data_length` does not match `height` and `width` /// /// # Safety /// /// The caller has to make sure that: /// - /// - `bitmap` points to a valid [SPBitmap] - /// - `bitmap` is not written to concurrently + /// - `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_bitmap_free`. + /// by explicitly calling `sp_cp437_grid_free`. /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Bitmap* sp_bitmap_clone(Bitmap* bitmap); + [DllImport(__DllName, EntryPoint = "sp_cp437_grid_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Cp437Grid* sp_cp437_grid_load(nuint width, nuint height, byte* data, nuint data_length); /// - /// Deallocates a [SPBitmap]. + /// Clones a [SPCp437Grid]. + /// + /// Will never return NULL. /// /// # Panics /// - /// - when `bitmap` is NULL + /// - when `cp437_grid` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `bitmap` points to a valid [SPBitmap] - /// - `bitmap` is not used concurrently or after bitmap call - /// - `bitmap` was not passed to another consuming function, e.g. to create a [SPCommand] + /// - `cp437_grid` points to a valid [SPCp437Grid] + /// - `cp437_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_cp437_grid_free`. /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitmap_free(Bitmap* bitmap); + [DllImport(__DllName, EntryPoint = "sp_cp437_grid_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Cp437Grid* sp_cp437_grid_clone(Cp437Grid* cp437_grid); /// - /// Gets the current value at the specified position in the [SPBitmap]. + /// Deallocates a [SPCp437Grid]. + /// + /// # Panics + /// + /// - when `cp437_grid` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `cp437_grid` points to a valid [SPCp437Grid] + /// - `cp437_grid` is not used concurrently or after cp437_grid call + /// - `cp437_grid` was not passed to another consuming function, e.g. to create a [SPCommand] + /// + [DllImport(__DllName, EntryPoint = "sp_cp437_grid_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_cp437_grid_free(Cp437Grid* cp437_grid); + + /// + /// Gets the current value at the specified position. /// /// # Arguments /// - /// - `bitmap`: instance to read from + /// - `cp437_grid`: instance to read from /// - `x` and `y`: position of the cell to read /// /// # Panics /// - /// - when `bitmap` is NULL + /// - when `cp437_grid` is NULL /// - when accessing `x` or `y` out of bounds /// /// # Safety /// /// The caller has to make sure that: /// - /// - `bitmap` points to a valid [SPBitmap] - /// - `bitmap` is not written to concurrently + /// - `cp437_grid` points to a valid [SPCp437Grid] + /// - `cp437_grid` is not written to concurrently /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_bitmap_get(Bitmap* bitmap, nuint x, nuint y); + [DllImport(__DllName, EntryPoint = "sp_cp437_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern byte sp_cp437_grid_get(Cp437Grid* cp437_grid, nuint x, nuint y); /// - /// Sets the value of the specified position in the [SPBitmap]. + /// Sets the value of the specified position in the [SPCp437Grid]. /// /// # Arguments /// - /// - `bitmap`: instance to write to + /// - `cp437_grid`: instance to write to /// - `x` and `y`: position of the cell /// - `value`: the value to write to the cell /// @@ -1298,98 +1296,100 @@ namespace ServicePoint.BindGen /// /// # Panics /// - /// - when `bitmap` is NULL + /// - when `cp437_grid` is NULL /// - when accessing `x` or `y` out of bounds /// /// # Safety /// /// The caller has to make sure that: /// - /// - `bitmap` points to a valid [SPBitmap] - /// - `bitmap` is not written to or read from concurrently + /// - `cp437_grid` points to a valid [SPBitVec] + /// - `cp437_grid` is not written to or read from concurrently /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitmap_set(Bitmap* bitmap, nuint x, nuint y, [MarshalAs(UnmanagedType.U1)] bool value); + [DllImport(__DllName, EntryPoint = "sp_cp437_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_cp437_grid_set(Cp437Grid* cp437_grid, nuint x, nuint y, byte value); /// - /// Sets the state of all pixels in the [SPBitmap]. + /// Sets the value of all cells in the [SPCp437Grid]. /// /// # Arguments /// - /// - `bitmap`: instance to write to - /// - `value`: the value to set all pixels to + /// - `cp437_grid`: instance to write to + /// - `value`: the value to set all cells to /// /// # Panics /// - /// - when `bitmap` is NULL + /// - when `cp437_grid` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `bitmap` points to a valid [SPBitmap] - /// - `bitmap` is not written to or read from concurrently + /// - `cp437_grid` points to a valid [SPCp437Grid] + /// - `cp437_grid` is not written to or read from concurrently /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitmap_fill(Bitmap* bitmap, [MarshalAs(UnmanagedType.U1)] bool value); + [DllImport(__DllName, EntryPoint = "sp_cp437_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_cp437_grid_fill(Cp437Grid* cp437_grid, byte value); /// - /// Gets the width in pixels of the [SPBitmap] instance. + /// Gets the width of the [SPCp437Grid] instance. /// /// # Arguments /// - /// - `bitmap`: instance to read from + /// - `cp437_grid`: instance to read from /// /// # Panics /// - /// - when `bitmap` is NULL + /// - when `cp437_grid` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `bitmap` points to a valid [SPBitmap] + /// - `cp437_grid` points to a valid [SPCp437Grid] /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_bitmap_width(Bitmap* bitmap); + [DllImport(__DllName, EntryPoint = "sp_cp437_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern nuint sp_cp437_grid_width(Cp437Grid* cp437_grid); /// - /// Gets the height in pixels of the [SPBitmap] instance. + /// Gets the height of the [SPCp437Grid] instance. /// /// # Arguments /// - /// - `bitmap`: instance to read from + /// - `cp437_grid`: instance to read from /// /// # Panics /// - /// - when `bitmap` is NULL + /// - when `cp437_grid` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `bitmap` points to a valid [SPBitmap] + /// - `cp437_grid` points to a valid [SPCp437Grid] /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_bitmap_height(Bitmap* bitmap); + [DllImport(__DllName, EntryPoint = "sp_cp437_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern nuint sp_cp437_grid_height(Cp437Grid* cp437_grid); /// - /// Gets an unsafe reference to the data of the [SPBitmap] instance. + /// Gets an unsafe reference to the data of the [SPCp437Grid] instance. + /// + /// Will never return NULL. /// /// # Panics /// - /// - when `bitmap` is NULL + /// - when `cp437_grid` is NULL /// - /// # Safety + /// ## Safety /// /// The caller has to make sure that: /// - /// - `bitmap` points to a valid [SPBitmap] - /// - the returned memory range is never accessed after the passed [SPBitmap] has been freed - /// - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly + /// - `cp437_grid` points to a valid [SPCp437Grid] + /// - the returned memory range is never accessed after the passed [SPCp437Grid] has been freed + /// - the returned memory range is never accessed concurrently, either via the [SPCp437Grid] or directly /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteSlice sp_bitmap_unsafe_data_ref(Bitmap* bitmap); + [DllImport(__DllName, EntryPoint = "sp_cp437_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern ByteSlice sp_cp437_grid_unsafe_data_ref(Cp437Grid* cp437_grid); } @@ -1399,11 +1399,6 @@ namespace ServicePoint.BindGen { } - [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct BrightnessGrid - { - } - [StructLayout(LayoutKind.Sequential)] public unsafe partial struct ByteSlice { @@ -1417,12 +1412,17 @@ namespace ServicePoint.BindGen } [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct Cp437Grid + public unsafe partial struct Packet { } [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct Packet + public unsafe partial struct BrightnessGrid + { + } + + [StructLayout(LayoutKind.Sequential)] + public unsafe partial struct Bitmap { } @@ -1432,7 +1432,7 @@ namespace ServicePoint.BindGen } [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct Bitmap + public unsafe partial struct Cp437Grid { } From 590b21d43389df918764c1ba566002011c7fb92e Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Tue, 15 Oct 2024 22:23:52 +0200 Subject: [PATCH 20/27] use NonNull as return type in C API --- crates/servicepoint_binding_c/src/bitmap.rs | 28 +++-- crates/servicepoint_binding_c/src/bitvec.rs | 24 ++-- .../src/brightness_grid.rs | 27 +++-- .../servicepoint_binding_c/src/byte_slice.rs | 4 +- crates/servicepoint_binding_c/src/command.rs | 105 ++++++++---------- .../servicepoint_binding_c/src/cp437_grid.rs | 28 +++-- crates/servicepoint_binding_c/src/packet.rs | 17 ++- 7 files changed, 105 insertions(+), 128 deletions(-) diff --git a/crates/servicepoint_binding_c/src/bitmap.rs b/crates/servicepoint_binding_c/src/bitmap.rs index 0c4271c..b327fd2 100644 --- a/crates/servicepoint_binding_c/src/bitmap.rs +++ b/crates/servicepoint_binding_c/src/bitmap.rs @@ -2,6 +2,7 @@ //! //! prefix `sp_bitmap_` +use std::ptr::NonNull; use servicepoint::{DataRef, Grid}; use crate::byte_slice::SPByteSlice; @@ -41,12 +42,11 @@ pub struct SPBitmap(pub(crate) servicepoint::Bitmap); pub unsafe extern "C" fn sp_bitmap_new( width: usize, height: usize, -) -> *mut SPBitmap { - let result = Box::into_raw(Box::new(SPBitmap(servicepoint::Bitmap::new( +) -> NonNull { + let result = Box::new(SPBitmap(servicepoint::Bitmap::new( width, height, - )))); - assert!(!result.is_null()); - result + ))); + NonNull::from(Box::leak(result)) } /// 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, data: *const u8, data_length: usize, -) -> *mut SPBitmap { +) -> NonNull { assert!(!data.is_null()); 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, - )))); - assert!(!result.is_null()); - result + ))); + NonNull::from(Box::leak(result)) } /// Clones a [SPBitmap]. @@ -106,11 +105,10 @@ pub unsafe extern "C" fn sp_bitmap_load( #[no_mangle] pub unsafe extern "C" fn sp_bitmap_clone( bitmap: *const SPBitmap, -) -> *mut SPBitmap { +) -> NonNull { assert!(!bitmap.is_null()); - let result = Box::into_raw(Box::new(SPBitmap((*bitmap).0.clone()))); - assert!(!result.is_null()); - result + let result = Box::new(SPBitmap((*bitmap).0.clone())); + NonNull::from(Box::leak(result)) } /// Deallocates a [SPBitmap]. @@ -277,7 +275,7 @@ pub unsafe extern "C" fn sp_bitmap_unsafe_data_ref( assert!(!bitmap.is_null()); let data = (*bitmap).0.data_ref_mut(); SPByteSlice { - start: data.as_mut_ptr_range().start, + start: NonNull::new(data.as_mut_ptr_range().start).unwrap(), length: data.len(), } } diff --git a/crates/servicepoint_binding_c/src/bitvec.rs b/crates/servicepoint_binding_c/src/bitvec.rs index 1fe509b..7f2258a 100644 --- a/crates/servicepoint_binding_c/src/bitvec.rs +++ b/crates/servicepoint_binding_c/src/bitvec.rs @@ -2,6 +2,7 @@ //! //! prefix `sp_bitvec_` +use std::ptr::NonNull; use crate::SPByteSlice; 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 /// by explicitly calling `sp_bitvec_free`. #[no_mangle] -pub unsafe extern "C" fn sp_bitvec_new(size: usize) -> *mut SPBitVec { - let result = Box::into_raw(Box::new(SPBitVec(BitVec::repeat(false, size)))); - assert!(!result.is_null()); - result +pub unsafe extern "C" fn sp_bitvec_new(size: usize) -> NonNull { + let result = Box::new(SPBitVec(BitVec::repeat(false, size))); + NonNull::from(Box::leak(result)) } /// 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( data: *const u8, data_length: usize, -) -> *mut SPBitVec { +) -> NonNull { assert!(!data.is_null()); let data = std::slice::from_raw_parts(data, data_length); - let result = Box::into_raw(Box::new(SPBitVec(BitVec::from_slice(data)))); - assert!(!result.is_null()); - result + let result = Box::new(SPBitVec(BitVec::from_slice(data))); + NonNull::from(Box::leak(result)) } /// Clones a [SPBitVec]. @@ -105,11 +104,10 @@ pub unsafe extern "C" fn sp_bitvec_load( #[no_mangle] pub unsafe extern "C" fn sp_bitvec_clone( bit_vec: *const SPBitVec, -) -> *mut SPBitVec { +) -> NonNull { assert!(!bit_vec.is_null()); - let result = Box::into_raw(Box::new((*bit_vec).clone())); - assert!(!result.is_null()); - result + let result = Box::new((*bit_vec).clone()); + NonNull::from(Box::leak(result)) } /// Deallocates a [SPBitVec]. @@ -278,7 +276,7 @@ pub unsafe extern "C" fn sp_bitvec_unsafe_data_ref( assert!(!bit_vec.is_null()); let data = (*bit_vec).0.as_raw_mut_slice(); SPByteSlice { - start: data.as_mut_ptr_range().start, + start: NonNull::new(data.as_mut_ptr_range().start).unwrap(), length: data.len(), } } diff --git a/crates/servicepoint_binding_c/src/brightness_grid.rs b/crates/servicepoint_binding_c/src/brightness_grid.rs index c1dc186..4a527fe 100644 --- a/crates/servicepoint_binding_c/src/brightness_grid.rs +++ b/crates/servicepoint_binding_c/src/brightness_grid.rs @@ -5,6 +5,7 @@ use crate::SPByteSlice; use servicepoint::{Brightness, DataRef, Grid, PrimitiveGrid}; use std::intrinsics::transmute; +use std::ptr::NonNull; /// 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( width: usize, height: usize, -) -> *mut SPBrightnessGrid { - let result = Box::into_raw(Box::new(SPBrightnessGrid( +) -> NonNull { + let result = Box::new(SPBrightnessGrid( servicepoint::BrightnessGrid::new(width, height), - ))); - assert!(!result.is_null()); - result + )); + NonNull::from(Box::leak(result)) } /// 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, data: *const u8, data_length: usize, -) -> *mut SPBrightnessGrid { +) -> NonNull { 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"); - let result = Box::into_raw(Box::new(SPBrightnessGrid(grid))); - assert!(!result.is_null()); - result + let result = Box::new(SPBrightnessGrid(grid)); + NonNull::from(Box::leak(result)) } /// Clones a [SPBrightnessGrid]. @@ -103,11 +102,10 @@ pub unsafe extern "C" fn sp_brightness_grid_load( #[no_mangle] pub unsafe extern "C" fn sp_brightness_grid_clone( brightness_grid: *const SPBrightnessGrid, -) -> *mut SPBrightnessGrid { +) -> NonNull { assert!(!brightness_grid.is_null()); - let result = Box::into_raw(Box::new((*brightness_grid).clone())); - assert!(!result.is_null()); - result + let result = Box::new((*brightness_grid).clone()); + NonNull::from(Box::leak(result)) } /// Deallocates a [SPBrightnessGrid]. @@ -305,9 +303,10 @@ pub unsafe extern "C" fn sp_brightness_grid_unsafe_data_ref( assert!(!brightness_grid.is_null()); assert_eq!(core::mem::size_of::(), 1); 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); SPByteSlice { - start: data.as_mut_ptr_range().start, + start: NonNull::new(data.as_mut_ptr_range().start).unwrap(), length: data.len(), } } diff --git a/crates/servicepoint_binding_c/src/byte_slice.rs b/crates/servicepoint_binding_c/src/byte_slice.rs index fbdda2a..678a5d7 100644 --- a/crates/servicepoint_binding_c/src/byte_slice.rs +++ b/crates/servicepoint_binding_c/src/byte_slice.rs @@ -1,5 +1,7 @@ //! FFI slice helper +use std::ptr::NonNull; + #[repr(C)] /// 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. pub struct SPByteSlice { /// The start address of the memory - pub start: *mut u8, + pub start: NonNull, /// The amount of memory in bytes pub length: usize, } diff --git a/crates/servicepoint_binding_c/src/command.rs b/crates/servicepoint_binding_c/src/command.rs index db86551..a4ebc1a 100644 --- a/crates/servicepoint_binding_c/src/command.rs +++ b/crates/servicepoint_binding_c/src/command.rs @@ -2,7 +2,7 @@ //! //! prefix `sp_command_` -use std::ptr::null_mut; +use std::ptr::{null_mut, NonNull}; use servicepoint::{Brightness, Origin}; @@ -80,11 +80,10 @@ pub unsafe extern "C" fn sp_command_try_from_packet( #[no_mangle] pub unsafe extern "C" fn sp_command_clone( command: *const SPCommand, -) -> *mut SPCommand { +) -> NonNull { assert!(!command.is_null()); - let result = Box::into_raw(Box::new((*command).clone())); - assert!(!result.is_null()); - result + let result = Box::new((*command).clone()); + NonNull::from(Box::leak(result)) } /// 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 /// by explicitly calling `sp_command_free`. #[no_mangle] -pub unsafe extern "C" fn sp_command_clear() -> *mut SPCommand { - let result = - Box::into_raw(Box::new(SPCommand(servicepoint::Command::Clear))); - assert!(!result.is_null()); - result +pub unsafe extern "C" fn sp_command_clear() -> NonNull { + let result = Box::new(SPCommand(servicepoint::Command::Clear)); + NonNull::from(Box::leak(result)) } /// 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 /// by explicitly calling `sp_command_free`. #[no_mangle] -pub unsafe extern "C" fn sp_command_hard_reset() -> *mut SPCommand { - let result = - Box::into_raw(Box::new(SPCommand(servicepoint::Command::HardReset))); - assert!(!result.is_null()); - result +pub unsafe extern "C" fn sp_command_hard_reset() -> NonNull { + let result = Box::new(SPCommand(servicepoint::Command::HardReset)); + NonNull::from(Box::leak(result)) } /// 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 /// by explicitly calling `sp_command_free`. #[no_mangle] -pub unsafe extern "C" fn sp_command_fade_out() -> *mut SPCommand { - let result = - Box::into_raw(Box::new(SPCommand(servicepoint::Command::FadeOut))); - assert!(!result.is_null()); - result +pub unsafe extern "C" fn sp_command_fade_out() -> NonNull { + let result = Box::new(SPCommand(servicepoint::Command::FadeOut)); + NonNull::from(Box::leak(result)) } /// 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] pub unsafe extern "C" fn sp_command_brightness( brightness: u8, -) -> *mut SPCommand { +) -> NonNull { let 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), - ))); - assert!(!result.is_null()); - result + )); + NonNull::from(Box::leak(result)) } /// 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, y: usize, grid: *mut SPBrightnessGrid, -) -> *mut SPCommand { +) -> NonNull { assert!(!grid.is_null()); 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), - ))); - assert!(!result.is_null()); - result + )); + NonNull::from(Box::leak(result)) } /// 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, bit_vec: *mut SPBitVec, compression: SPCompressionCode, -) -> *mut SPCommand { +) -> NonNull { assert!(!bit_vec.is_null()); let bit_vec = *Box::from_raw(bit_vec); - let result = Box::into_raw(Box::new(SPCommand( + let result = Box::new(SPCommand( servicepoint::Command::BitmapLinear( offset, bit_vec.into(), compression.try_into().expect("invalid compression code"), ), - ))); - assert!(!result.is_null()); - result + )); + NonNull::from(Box::leak(result)) } /// 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, bit_vec: *mut SPBitVec, compression: SPCompressionCode, -) -> *mut SPCommand { +) -> NonNull { assert!(!bit_vec.is_null()); let bit_vec = *Box::from_raw(bit_vec); - let result = Box::into_raw(Box::new(SPCommand( + let result = Box::new(SPCommand( servicepoint::Command::BitmapLinearAnd( offset, bit_vec.into(), compression.try_into().expect("invalid compression code"), ), - ))); - assert!(!result.is_null()); - result + )); + NonNull::from(Box::leak(result)) } /// 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, bit_vec: *mut SPBitVec, compression: SPCompressionCode, -) -> *mut SPCommand { +) -> NonNull { assert!(!bit_vec.is_null()); let bit_vec = *Box::from_raw(bit_vec); - let result = Box::into_raw(Box::new(SPCommand( + let result = Box::new(SPCommand( servicepoint::Command::BitmapLinearOr( offset, bit_vec.into(), compression.try_into().expect("invalid compression code"), ), - ))); - assert!(!result.is_null()); - result + )); + NonNull::from(Box::leak(result)) } /// 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, bit_vec: *mut SPBitVec, compression: SPCompressionCode, -) -> *mut SPCommand { +) -> NonNull { assert!(!bit_vec.is_null()); let bit_vec = *Box::from_raw(bit_vec); - let result = Box::into_raw(Box::new(SPCommand( + let result = Box::new(SPCommand( servicepoint::Command::BitmapLinearXor( offset, bit_vec.into(), compression.try_into().expect("invalid compression code"), ), - ))); - assert!(!result.is_null()); - result + )); + NonNull::from(Box::leak(result)) } /// Show text on the screen. @@ -410,14 +397,13 @@ pub unsafe extern "C" fn sp_command_cp437_data( x: usize, y: usize, grid: *mut SPCp437Grid, -) -> *mut SPCommand { +) -> NonNull { assert!(!grid.is_null()); 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), - ))); - assert!(!result.is_null()); - result + )); + NonNull::from(Box::leak(result)) } /// 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, bitmap: *mut SPBitmap, compression_code: SPCompressionCode, -) -> *mut SPCommand { +) -> NonNull { assert!(!bitmap.is_null()); let byte_grid = (*Box::from_raw(bitmap)).0; - let result = Box::into_raw(Box::new(SPCommand( + let result = Box::new(SPCommand( servicepoint::Command::BitmapLinearWin( Origin::new(x, y), byte_grid, @@ -457,9 +443,8 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_win( .try_into() .expect("invalid compression code"), ), - ))); - assert!(!result.is_null()); - result + )); + NonNull::from(Box::leak(result)) } /// Deallocates a [SPCommand]. diff --git a/crates/servicepoint_binding_c/src/cp437_grid.rs b/crates/servicepoint_binding_c/src/cp437_grid.rs index e458a1b..b940ae4 100644 --- a/crates/servicepoint_binding_c/src/cp437_grid.rs +++ b/crates/servicepoint_binding_c/src/cp437_grid.rs @@ -2,6 +2,7 @@ //! //! prefix `sp_cp437_grid_` +use std::ptr::NonNull; use crate::SPByteSlice; use servicepoint::{DataRef, Grid}; @@ -39,12 +40,11 @@ impl Clone for SPCp437Grid { pub unsafe extern "C" fn sp_cp437_grid_new( width: usize, height: usize, -) -> *mut SPCp437Grid { - let result = Box::into_raw(Box::new(SPCp437Grid( +) -> NonNull { + let result = Box::new(SPCp437Grid( servicepoint::Cp437Grid::new(width, height), - ))); - assert!(!result.is_null()); - result + )); + NonNull::from(Box::leak(result)) } /// 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, data: *const u8, data_length: usize, -) -> *mut SPCp437Grid { +) -> NonNull { assert!(data.is_null()); 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), - ))); - assert!(!result.is_null()); - result + )); + NonNull::from(Box::leak(result)) } /// Clones a [SPCp437Grid]. @@ -99,11 +98,10 @@ pub unsafe extern "C" fn sp_cp437_grid_load( #[no_mangle] pub unsafe extern "C" fn sp_cp437_grid_clone( cp437_grid: *const SPCp437Grid, -) -> *mut SPCp437Grid { +) -> NonNull { assert!(!cp437_grid.is_null()); - let result = Box::into_raw(Box::new((*cp437_grid).clone())); - assert!(!result.is_null()); - result + let result = Box::new((*cp437_grid).clone()); + NonNull::from(Box::leak(result)) } /// Deallocates a [SPCp437Grid]. @@ -278,7 +276,7 @@ pub unsafe extern "C" fn sp_cp437_grid_unsafe_data_ref( ) -> SPByteSlice { let data = (*cp437_grid).0.data_ref_mut(); SPByteSlice { - start: data.as_mut_ptr_range().start, + start: NonNull::new(data.as_mut_ptr_range().start).unwrap(), length: data.len(), } } diff --git a/crates/servicepoint_binding_c/src/packet.rs b/crates/servicepoint_binding_c/src/packet.rs index f2cffc4..e44c23f 100644 --- a/crates/servicepoint_binding_c/src/packet.rs +++ b/crates/servicepoint_binding_c/src/packet.rs @@ -2,7 +2,7 @@ //! //! prefix `sp_packet_` -use std::ptr::null_mut; +use std::ptr::{null_mut, NonNull}; use crate::SPCommand; @@ -29,13 +29,11 @@ pub struct SPPacket(pub(crate) servicepoint::packet::Packet); #[no_mangle] pub unsafe extern "C" fn sp_packet_from_command( command: *mut SPCommand, -) -> *mut SPPacket { +) -> NonNull { assert!(!command.is_null()); let command = *Box::from_raw(command); - let packet = SPPacket(command.0.into()); - let result = Box::into_raw(Box::new(packet)); - assert!(!result.is_null()); - result + let result = Box::new(SPPacket(command.0.into())); + NonNull::from(Box::leak(result)) } /// 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] pub unsafe extern "C" fn sp_packet_clone( packet: *const SPPacket, -) -> *mut SPPacket { +) -> NonNull { assert!(!packet.is_null()); - let result = Box::into_raw(Box::new(SPPacket((*packet).0.clone()))); - assert!(!result.is_null()); - result + let result = Box::new(SPPacket((*packet).0.clone())); + NonNull::from(Box::leak(result)) } /// Deallocates a [SPPacket]. From a858261540a06a5445bcdb1ab02d19314ac2f691 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Tue, 15 Oct 2024 22:54:32 +0200 Subject: [PATCH 21/27] use constants from generated file --- .../ServicePoint/BindGen/ServicePoint.g.cs | 444 +++++++++--------- .../ServicePoint/Constants.cs | 8 +- 2 files changed, 227 insertions(+), 225 deletions(-) diff --git a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs b/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs index abd6fd5..210d54e 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs @@ -19,224 +19,6 @@ namespace ServicePoint.BindGen public const nuint SP_TILE_HEIGHT = 20; - /// - /// Creates a new [SPBitVec] instance. - /// - /// # Arguments - /// - /// - `size`: size in bits. - /// - /// returns: [SPBitVec] with all bits set to false. Will never return NULL. - /// - /// # Panics - /// - /// - when `size` is not divisible by 8. - /// - /// # 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_bitvec_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BitVec* sp_bitvec_new(nuint size); - - /// - /// Interpret the data as a series of bits and load then into a new [SPBitVec] instance. - /// - /// returns: [SPBitVec] instance containing data. Will never return NULL. - /// - /// # Panics - /// - /// - when `data` is NULL - /// - /// # 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_bitvec_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BitVec* sp_bitvec_load(byte* data, nuint data_length); - - /// - /// Clones a [SPBitVec]. - /// - /// returns: new [SPBitVec] instance. Will never return NULL. - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - `bit_vec` is not written to concurrently - /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_bitvec_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BitVec* sp_bitvec_clone(BitVec* bit_vec); - - /// - /// Deallocates a [SPBitVec]. - /// - /// # Panics - /// - /// - when `but_vec` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - `bit_vec` is not used concurrently or after this call - /// - `bit_vec` was not passed to another consuming function, e.g. to create a [SPCommand] - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitvec_free(BitVec* bit_vec); - - /// - /// Gets the value of a bit from the [SPBitVec]. - /// - /// # Arguments - /// - /// - `bit_vec`: instance to read from - /// - `index`: the bit index to read - /// - /// returns: value of the bit - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - when accessing `index` out of bounds - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - `bit_vec` is not written to concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_bitvec_get(BitVec* bit_vec, nuint index); - - /// - /// Sets the value of a bit in the [SPBitVec]. - /// - /// # Arguments - /// - /// - `bit_vec`: instance to write to - /// - `index`: the bit index to edit - /// - `value`: the value to set the bit to - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - when accessing `index` out of bounds - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - `bit_vec` is not written to or read from concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitvec_set(BitVec* bit_vec, nuint index, [MarshalAs(UnmanagedType.U1)] bool value); - - /// - /// Sets the value of all bits in the [SPBitVec]. - /// - /// # Arguments - /// - /// - `bit_vec`: instance to write to - /// - `value`: the value to set all bits to - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - `bit_vec` is not written to or read from concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitvec_fill(BitVec* bit_vec, [MarshalAs(UnmanagedType.U1)] bool value); - - /// - /// Gets the length of the [SPBitVec] in bits. - /// - /// # Arguments - /// - /// - `bit_vec`: instance to write to - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_len", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_bitvec_len(BitVec* bit_vec); - - /// - /// Returns true if length is 0. - /// - /// # Arguments - /// - /// - `bit_vec`: instance to write to - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_is_empty", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_bitvec_is_empty(BitVec* bit_vec); - - /// - /// Gets an unsafe reference to the data of the [SPBitVec] instance. - /// - /// # Arguments - /// - /// - `bit_vec`: instance to write to - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - /// ## Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - the returned memory range is never accessed after the passed [SPBitVec] has been freed - /// - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteSlice sp_bitvec_unsafe_data_ref(BitVec* bit_vec); - /// /// Creates a new instance of [SPConnection]. /// @@ -1391,12 +1173,225 @@ namespace ServicePoint.BindGen [DllImport(__DllName, EntryPoint = "sp_cp437_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern ByteSlice sp_cp437_grid_unsafe_data_ref(Cp437Grid* cp437_grid); + /// + /// Creates a new [SPBitVec] instance. + /// + /// # Arguments + /// + /// - `size`: size in bits. + /// + /// returns: [SPBitVec] with all bits set to false. Will never return NULL. + /// + /// # Panics + /// + /// - when `size` is not divisible by 8. + /// + /// # 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_bitvec_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_bitvec_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern BitVec* sp_bitvec_new(nuint size); + + /// + /// Interpret the data as a series of bits and load then into a new [SPBitVec] instance. + /// + /// returns: [SPBitVec] instance containing data. Will never return NULL. + /// + /// # Panics + /// + /// - when `data` is NULL + /// + /// # 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_bitvec_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_bitvec_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern BitVec* sp_bitvec_load(byte* data, nuint data_length); + + /// + /// Clones a [SPBitVec]. + /// + /// returns: new [SPBitVec] instance. Will never return NULL. + /// + /// # Panics + /// + /// - when `bit_vec` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bit_vec` points to a valid [SPBitVec] + /// - `bit_vec` is not written to concurrently + /// - the returned instance is freed in some way, either by using a consuming function or + /// by explicitly calling `sp_bitvec_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_bitvec_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern BitVec* sp_bitvec_clone(BitVec* bit_vec); + + /// + /// Deallocates a [SPBitVec]. + /// + /// # Panics + /// + /// - when `but_vec` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bit_vec` points to a valid [SPBitVec] + /// - `bit_vec` is not used concurrently or after this call + /// - `bit_vec` was not passed to another consuming function, e.g. to create a [SPCommand] + /// + [DllImport(__DllName, EntryPoint = "sp_bitvec_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bitvec_free(BitVec* bit_vec); + + /// + /// Gets the value of a bit from the [SPBitVec]. + /// + /// # Arguments + /// + /// - `bit_vec`: instance to read from + /// - `index`: the bit index to read + /// + /// returns: value of the bit + /// + /// # Panics + /// + /// - when `bit_vec` is NULL + /// - when accessing `index` out of bounds + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bit_vec` points to a valid [SPBitVec] + /// - `bit_vec` is not written to concurrently + /// + [DllImport(__DllName, EntryPoint = "sp_bitvec_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.U1)] + public static extern bool sp_bitvec_get(BitVec* bit_vec, nuint index); + + /// + /// Sets the value of a bit in the [SPBitVec]. + /// + /// # Arguments + /// + /// - `bit_vec`: instance to write to + /// - `index`: the bit index to edit + /// - `value`: the value to set the bit to + /// + /// # Panics + /// + /// - when `bit_vec` is NULL + /// - when accessing `index` out of bounds + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bit_vec` points to a valid [SPBitVec] + /// - `bit_vec` is not written to or read from concurrently + /// + [DllImport(__DllName, EntryPoint = "sp_bitvec_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bitvec_set(BitVec* bit_vec, nuint index, [MarshalAs(UnmanagedType.U1)] bool value); + + /// + /// Sets the value of all bits in the [SPBitVec]. + /// + /// # Arguments + /// + /// - `bit_vec`: instance to write to + /// - `value`: the value to set all bits to + /// + /// # Panics + /// + /// - when `bit_vec` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bit_vec` points to a valid [SPBitVec] + /// - `bit_vec` is not written to or read from concurrently + /// + [DllImport(__DllName, EntryPoint = "sp_bitvec_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bitvec_fill(BitVec* bit_vec, [MarshalAs(UnmanagedType.U1)] bool value); + + /// + /// Gets the length of the [SPBitVec] in bits. + /// + /// # Arguments + /// + /// - `bit_vec`: instance to write to + /// + /// # Panics + /// + /// - when `bit_vec` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bit_vec` points to a valid [SPBitVec] + /// + [DllImport(__DllName, EntryPoint = "sp_bitvec_len", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern nuint sp_bitvec_len(BitVec* bit_vec); + + /// + /// Returns true if length is 0. + /// + /// # Arguments + /// + /// - `bit_vec`: instance to write to + /// + /// # Panics + /// + /// - when `bit_vec` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bit_vec` points to a valid [SPBitVec] + /// + [DllImport(__DllName, EntryPoint = "sp_bitvec_is_empty", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.U1)] + public static extern bool sp_bitvec_is_empty(BitVec* bit_vec); + + /// + /// Gets an unsafe reference to the data of the [SPBitVec] instance. + /// + /// # Arguments + /// + /// - `bit_vec`: instance to write to + /// + /// # Panics + /// + /// - when `bit_vec` is NULL + /// + /// ## Safety + /// + /// The caller has to make sure that: + /// + /// - `bit_vec` points to a valid [SPBitVec] + /// - the returned memory range is never accessed after the passed [SPBitVec] has been freed + /// - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly + /// + [DllImport(__DllName, EntryPoint = "sp_bitvec_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern ByteSlice sp_bitvec_unsafe_data_ref(BitVec* bit_vec); - } - [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct BitVec - { } [StructLayout(LayoutKind.Sequential)] @@ -1436,6 +1431,11 @@ namespace ServicePoint.BindGen { } + [StructLayout(LayoutKind.Sequential)] + public unsafe partial struct BitVec + { + } + public enum CompressionCode : ushort { diff --git a/crates/servicepoint_binding_cs/ServicePoint/Constants.cs b/crates/servicepoint_binding_cs/ServicePoint/Constants.cs index 9980f64..fea5c55 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/Constants.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/Constants.cs @@ -1,15 +1,17 @@ +using ServicePoint.BindGen; + namespace ServicePoint; public static class Constants { /// size of a single tile in one dimension - public const int TileSize = 8; + public const int TileSize = NativeMethods.SP_TILE_SIZE; /// tile count in the x-direction - public const int TileWidth = 56; + public const int TileWidth = NativeMethods.SP_TILE_WIDTH; /// tile count in the y-direction - public const int TileHeight = 20; + public const int TileHeight = NativeMethods.SP_TILE_SIZE; /// screen width in pixels public const int PixelWidth = TileWidth * TileSize; From 16a0afe08d63161615ed21dd2189a39a3682ca99 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 16 Oct 2024 18:29:36 +0200 Subject: [PATCH 22/27] add constants for brightness in C api --- .../examples/lang_c/include/servicepoint.h | 15 +++++++++++++++ .../servicepoint_binding_c/src/brightness_grid.rs | 8 ++++++++ .../ServicePoint/BindGen/ServicePoint.g.cs | 3 +++ 3 files changed, 26 insertions(+) diff --git a/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h b/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h index 617cdeb..118c36b 100644 --- a/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h +++ b/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h @@ -8,6 +8,21 @@ #include #include +/** + * Count of possible brightness values + */ +#define SP_BRIGHTNESS_LEVELS 12 + +/** + * see [Brightness::MAX] + */ +#define SP_BRIGHTNESS_MAX 11 + +/** + * see [Brightness::MIN] + */ +#define SP_BRIGHTNESS_MIN 0 + /** * pixel count on whole screen */ diff --git a/crates/servicepoint_binding_c/src/brightness_grid.rs b/crates/servicepoint_binding_c/src/brightness_grid.rs index 4a527fe..3c94b57 100644 --- a/crates/servicepoint_binding_c/src/brightness_grid.rs +++ b/crates/servicepoint_binding_c/src/brightness_grid.rs @@ -4,9 +4,17 @@ use crate::SPByteSlice; use servicepoint::{Brightness, DataRef, Grid, PrimitiveGrid}; +use std::convert::Into; use std::intrinsics::transmute; use std::ptr::NonNull; +/// see [Brightness::MIN] +pub const SP_BRIGHTNESS_MIN: u8 = 0; +/// see [Brightness::MAX] +pub const SP_BRIGHTNESS_MAX: u8 = 11; +/// Count of possible brightness values +pub const SP_BRIGHTNESS_LEVELS: u8 = 12; + /// A grid containing brightness values. /// /// # Examples diff --git a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs b/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs index 210d54e..2b5f14e 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs @@ -17,6 +17,9 @@ namespace ServicePoint.BindGen public const nuint SP_TILE_SIZE = 8; public const nuint SP_TILE_WIDTH = 56; public const nuint SP_TILE_HEIGHT = 20; + public const byte SP_BRIGHTNESS_MIN = 0; + public const byte SP_BRIGHTNESS_MAX = 11; + public const byte SP_BRIGHTNESS_LEVELS = 12; /// From 97a994fca2da7e619164c646170b2a18241c5a55 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 16 Oct 2024 18:34:21 +0200 Subject: [PATCH 23/27] do not name struct in C api --- crates/servicepoint_binding_c/cbindgen.toml | 2 +- .../examples/lang_c/include/servicepoint.h | 191 +++++++++--------- 2 files changed, 95 insertions(+), 98 deletions(-) diff --git a/crates/servicepoint_binding_c/cbindgen.toml b/crates/servicepoint_binding_c/cbindgen.toml index cbf9e14..7fc0fdf 100644 --- a/crates/servicepoint_binding_c/cbindgen.toml +++ b/crates/servicepoint_binding_c/cbindgen.toml @@ -16,7 +16,7 @@ line_endings = "LF" ############################# Codegen Options ################################## -style = "both" +style = "type" usize_is_size_t = true # this is needed because otherwise the order in the C# bindings is different on different machines diff --git a/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h b/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h index 118c36b..fec0ff0 100644 --- a/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h +++ b/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h @@ -196,7 +196,7 @@ typedef struct SPPacket SPPacket; * - an instance of this created from C is never passed to a consuming function, as the rust code * will try to free the memory of a potentially separate allocator. */ -typedef struct SPByteSlice { +typedef struct { /** * The start address of the memory */ @@ -229,7 +229,7 @@ extern "C" { * - the returned instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_bitmap_free`. */ -struct SPBitmap *sp_bitmap_clone(const struct SPBitmap *bitmap); +SPBitmap *sp_bitmap_clone(const SPBitmap *bitmap); /** * Sets the state of all pixels in the [SPBitmap]. @@ -250,7 +250,7 @@ struct SPBitmap *sp_bitmap_clone(const struct SPBitmap *bitmap); * - `bitmap` points to a valid [SPBitmap] * - `bitmap` is not written to or read from concurrently */ -void sp_bitmap_fill(struct SPBitmap *bitmap, bool value); +void sp_bitmap_fill(SPBitmap *bitmap, bool value); /** * Deallocates a [SPBitmap]. @@ -267,7 +267,7 @@ void sp_bitmap_fill(struct SPBitmap *bitmap, bool value); * - `bitmap` is not used concurrently or after bitmap call * - `bitmap` was not passed to another consuming function, e.g. to create a [SPCommand] */ -void sp_bitmap_free(struct SPBitmap *bitmap); +void sp_bitmap_free(SPBitmap *bitmap); /** * Gets the current value at the specified position in the [SPBitmap]. @@ -289,7 +289,7 @@ void sp_bitmap_free(struct SPBitmap *bitmap); * - `bitmap` points to a valid [SPBitmap] * - `bitmap` is not written to concurrently */ -bool sp_bitmap_get(const struct SPBitmap *bitmap, size_t x, size_t y); +bool sp_bitmap_get(const SPBitmap *bitmap, size_t x, size_t y); /** * Gets the height in pixels of the [SPBitmap] instance. @@ -308,7 +308,7 @@ bool sp_bitmap_get(const struct SPBitmap *bitmap, size_t x, size_t y); * * - `bitmap` points to a valid [SPBitmap] */ -size_t sp_bitmap_height(const struct SPBitmap *bitmap); +size_t sp_bitmap_height(const SPBitmap *bitmap); /** * Loads a [SPBitmap] with the specified dimensions from the provided data. @@ -334,10 +334,10 @@ size_t sp_bitmap_height(const struct SPBitmap *bitmap); * - the returned instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_bitmap_free`. */ -struct SPBitmap *sp_bitmap_load(size_t width, - size_t height, - const uint8_t *data, - size_t data_length); +SPBitmap *sp_bitmap_load(size_t width, + size_t height, + const uint8_t *data, + size_t data_length); /** * Creates a new [SPBitmap] with the specified dimensions. @@ -360,8 +360,8 @@ struct SPBitmap *sp_bitmap_load(size_t width, * - the returned instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_bitmap_free`. */ -struct SPBitmap *sp_bitmap_new(size_t width, - size_t height); +SPBitmap *sp_bitmap_new(size_t width, + size_t height); /** * Sets the value of the specified position in the [SPBitmap]. @@ -386,7 +386,7 @@ struct SPBitmap *sp_bitmap_new(size_t width, * - `bitmap` points to a valid [SPBitmap] * - `bitmap` is not written to or read from concurrently */ -void sp_bitmap_set(struct SPBitmap *bitmap, size_t x, size_t y, bool value); +void sp_bitmap_set(SPBitmap *bitmap, size_t x, size_t y, bool value); /** * Gets an unsafe reference to the data of the [SPBitmap] instance. @@ -403,7 +403,7 @@ void sp_bitmap_set(struct SPBitmap *bitmap, size_t x, size_t y, bool value); * - the returned memory range is never accessed after the passed [SPBitmap] has been freed * - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly */ -struct SPByteSlice sp_bitmap_unsafe_data_ref(struct SPBitmap *bitmap); +SPByteSlice sp_bitmap_unsafe_data_ref(SPBitmap *bitmap); /** * Gets the width in pixels of the [SPBitmap] instance. @@ -422,7 +422,7 @@ struct SPByteSlice sp_bitmap_unsafe_data_ref(struct SPBitmap *bitmap); * * - `bitmap` points to a valid [SPBitmap] */ -size_t sp_bitmap_width(const struct SPBitmap *bitmap); +size_t sp_bitmap_width(const SPBitmap *bitmap); /** * Clones a [SPBitVec]. @@ -442,7 +442,7 @@ size_t sp_bitmap_width(const struct SPBitmap *bitmap); * - the returned instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_bitvec_free`. */ -struct SPBitVec *sp_bitvec_clone(const struct SPBitVec *bit_vec); +SPBitVec *sp_bitvec_clone(const SPBitVec *bit_vec); /** * Sets the value of all bits in the [SPBitVec]. @@ -463,7 +463,7 @@ struct SPBitVec *sp_bitvec_clone(const struct SPBitVec *bit_vec); * - `bit_vec` points to a valid [SPBitVec] * - `bit_vec` is not written to or read from concurrently */ -void sp_bitvec_fill(struct SPBitVec *bit_vec, bool value); +void sp_bitvec_fill(SPBitVec *bit_vec, bool value); /** * Deallocates a [SPBitVec]. @@ -480,7 +480,7 @@ void sp_bitvec_fill(struct SPBitVec *bit_vec, bool value); * - `bit_vec` is not used concurrently or after this call * - `bit_vec` was not passed to another consuming function, e.g. to create a [SPCommand] */ -void sp_bitvec_free(struct SPBitVec *bit_vec); +void sp_bitvec_free(SPBitVec *bit_vec); /** * Gets the value of a bit from the [SPBitVec]. @@ -504,7 +504,7 @@ void sp_bitvec_free(struct SPBitVec *bit_vec); * - `bit_vec` points to a valid [SPBitVec] * - `bit_vec` is not written to concurrently */ -bool sp_bitvec_get(const struct SPBitVec *bit_vec, size_t index); +bool sp_bitvec_get(const SPBitVec *bit_vec, size_t index); /** * Returns true if length is 0. @@ -523,7 +523,7 @@ bool sp_bitvec_get(const struct SPBitVec *bit_vec, size_t index); * * - `bit_vec` points to a valid [SPBitVec] */ -bool sp_bitvec_is_empty(const struct SPBitVec *bit_vec); +bool sp_bitvec_is_empty(const SPBitVec *bit_vec); /** * Gets the length of the [SPBitVec] in bits. @@ -542,7 +542,7 @@ bool sp_bitvec_is_empty(const struct SPBitVec *bit_vec); * * - `bit_vec` points to a valid [SPBitVec] */ -size_t sp_bitvec_len(const struct SPBitVec *bit_vec); +size_t sp_bitvec_len(const SPBitVec *bit_vec); /** * Interpret the data as a series of bits and load then into a new [SPBitVec] instance. @@ -562,8 +562,8 @@ size_t sp_bitvec_len(const struct SPBitVec *bit_vec); * - the returned instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_bitvec_free`. */ -struct SPBitVec *sp_bitvec_load(const uint8_t *data, - size_t data_length); +SPBitVec *sp_bitvec_load(const uint8_t *data, + size_t data_length); /** * Creates a new [SPBitVec] instance. @@ -585,7 +585,7 @@ struct SPBitVec *sp_bitvec_load(const uint8_t *data, * - the returned instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_bitvec_free`. */ -struct SPBitVec *sp_bitvec_new(size_t size); +SPBitVec *sp_bitvec_new(size_t size); /** * Sets the value of a bit in the [SPBitVec]. @@ -608,7 +608,7 @@ struct SPBitVec *sp_bitvec_new(size_t size); * - `bit_vec` points to a valid [SPBitVec] * - `bit_vec` is not written to or read from concurrently */ -void sp_bitvec_set(struct SPBitVec *bit_vec, size_t index, bool value); +void sp_bitvec_set(SPBitVec *bit_vec, size_t index, bool value); /** * Gets an unsafe reference to the data of the [SPBitVec] instance. @@ -629,7 +629,7 @@ void sp_bitvec_set(struct SPBitVec *bit_vec, size_t index, bool value); * - the returned memory range is never accessed after the passed [SPBitVec] has been freed * - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly */ -struct SPByteSlice sp_bitvec_unsafe_data_ref(struct SPBitVec *bit_vec); +SPByteSlice sp_bitvec_unsafe_data_ref(SPBitVec *bit_vec); /** * Clones a [SPBrightnessGrid]. @@ -653,7 +653,7 @@ struct SPByteSlice sp_bitvec_unsafe_data_ref(struct SPBitVec *bit_vec); * - the returned instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_brightness_grid_free`. */ -struct SPBrightnessGrid *sp_brightness_grid_clone(const struct SPBrightnessGrid *brightness_grid); +SPBrightnessGrid *sp_brightness_grid_clone(const SPBrightnessGrid *brightness_grid); /** * Sets the value of all cells in the [SPBrightnessGrid]. @@ -675,8 +675,7 @@ struct SPBrightnessGrid *sp_brightness_grid_clone(const struct SPBrightnessGrid * - `brightness_grid` points to a valid [SPBrightnessGrid] * - `brightness_grid` is not written to or read from concurrently */ -void sp_brightness_grid_fill(struct SPBrightnessGrid *brightness_grid, - uint8_t value); +void sp_brightness_grid_fill(SPBrightnessGrid *brightness_grid, uint8_t value); /** * Deallocates a [SPBrightnessGrid]. @@ -697,7 +696,7 @@ void sp_brightness_grid_fill(struct SPBrightnessGrid *brightness_grid, * - `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] */ -void sp_brightness_grid_free(struct SPBrightnessGrid *brightness_grid); +void sp_brightness_grid_free(SPBrightnessGrid *brightness_grid); /** * Gets the current value at the specified position. @@ -721,7 +720,7 @@ void sp_brightness_grid_free(struct SPBrightnessGrid *brightness_grid); * - `brightness_grid` points to a valid [SPBrightnessGrid] * - `brightness_grid` is not written to concurrently */ -uint8_t sp_brightness_grid_get(const struct SPBrightnessGrid *brightness_grid, +uint8_t sp_brightness_grid_get(const SPBrightnessGrid *brightness_grid, size_t x, size_t y); @@ -744,7 +743,7 @@ uint8_t sp_brightness_grid_get(const struct SPBrightnessGrid *brightness_grid, * * - `brightness_grid` points to a valid [SPBrightnessGrid] */ -size_t sp_brightness_grid_height(const struct SPBrightnessGrid *brightness_grid); +size_t sp_brightness_grid_height(const SPBrightnessGrid *brightness_grid); /** * Loads a [SPBrightnessGrid] with the specified dimensions from the provided data. @@ -765,10 +764,10 @@ size_t sp_brightness_grid_height(const struct SPBrightnessGrid *brightness_grid) * - the returned instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_brightness_grid_free`. */ -struct SPBrightnessGrid *sp_brightness_grid_load(size_t width, - size_t height, - const uint8_t *data, - size_t data_length); +SPBrightnessGrid *sp_brightness_grid_load(size_t width, + size_t height, + const uint8_t *data, + size_t data_length); /** * Creates a new [SPBrightnessGrid] with the specified dimensions. @@ -782,8 +781,8 @@ struct SPBrightnessGrid *sp_brightness_grid_load(size_t width, * - the returned instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_brightness_grid_free`. */ -struct SPBrightnessGrid *sp_brightness_grid_new(size_t width, - size_t height); +SPBrightnessGrid *sp_brightness_grid_new(size_t width, + size_t height); /** * Sets the value of the specified position in the [SPBrightnessGrid]. @@ -809,7 +808,7 @@ struct SPBrightnessGrid *sp_brightness_grid_new(size_t width, * - `brightness_grid` points to a valid [SPBitVec] * - `brightness_grid` is not written to or read from concurrently */ -void sp_brightness_grid_set(struct SPBrightnessGrid *brightness_grid, +void sp_brightness_grid_set(SPBrightnessGrid *brightness_grid, size_t x, size_t y, uint8_t value); @@ -835,7 +834,7 @@ void sp_brightness_grid_set(struct SPBrightnessGrid *brightness_grid, * - 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 */ -struct SPByteSlice sp_brightness_grid_unsafe_data_ref(struct SPBrightnessGrid *brightness_grid); +SPByteSlice sp_brightness_grid_unsafe_data_ref(SPBrightnessGrid *brightness_grid); /** * Gets the width of the [SPBrightnessGrid] instance. @@ -856,7 +855,7 @@ struct SPByteSlice sp_brightness_grid_unsafe_data_ref(struct SPBrightnessGrid *b * * - `brightness_grid` points to a valid [SPBrightnessGrid] */ -size_t sp_brightness_grid_width(const struct SPBrightnessGrid *brightness_grid); +size_t sp_brightness_grid_width(const SPBrightnessGrid *brightness_grid); /** * Set pixel data starting at the pixel offset on screen. @@ -885,9 +884,9 @@ size_t sp_brightness_grid_width(const struct SPBrightnessGrid *brightness_grid); * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_command_free`. */ -struct SPCommand *sp_command_bitmap_linear(size_t offset, - struct SPBitVec *bit_vec, - SPCompressionCode compression); +SPCommand *sp_command_bitmap_linear(size_t offset, + SPBitVec *bit_vec, + SPCompressionCode compression); /** * Set pixel data according to an and-mask starting at the offset. @@ -916,9 +915,9 @@ struct SPCommand *sp_command_bitmap_linear(size_t offset, * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_command_free`. */ -struct SPCommand *sp_command_bitmap_linear_and(size_t offset, - struct SPBitVec *bit_vec, - SPCompressionCode compression); +SPCommand *sp_command_bitmap_linear_and(size_t offset, + SPBitVec *bit_vec, + SPCompressionCode compression); /** * Set pixel data according to an or-mask starting at the offset. @@ -947,9 +946,9 @@ struct SPCommand *sp_command_bitmap_linear_and(size_t offset, * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_command_free`. */ -struct SPCommand *sp_command_bitmap_linear_or(size_t offset, - struct SPBitVec *bit_vec, - SPCompressionCode compression); +SPCommand *sp_command_bitmap_linear_or(size_t offset, + SPBitVec *bit_vec, + SPCompressionCode compression); /** * Sets a window of pixels to the specified values. @@ -973,10 +972,10 @@ struct SPCommand *sp_command_bitmap_linear_or(size_t offset, * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_command_free`. */ -struct SPCommand *sp_command_bitmap_linear_win(size_t x, - size_t y, - struct SPBitmap *bitmap, - SPCompressionCode compression_code); +SPCommand *sp_command_bitmap_linear_win(size_t x, + size_t y, + SPBitmap *bitmap, + SPCompressionCode compression_code); /** * Set pixel data according to a xor-mask starting at the offset. @@ -1005,9 +1004,9 @@ struct SPCommand *sp_command_bitmap_linear_win(size_t x, * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_command_free`. */ -struct SPCommand *sp_command_bitmap_linear_xor(size_t offset, - struct SPBitVec *bit_vec, - SPCompressionCode compression); +SPCommand *sp_command_bitmap_linear_xor(size_t offset, + SPBitVec *bit_vec, + SPCompressionCode compression); /** * Set the brightness of all tiles to the same value. @@ -1025,7 +1024,7 @@ struct SPCommand *sp_command_bitmap_linear_xor(size_t offset, * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_command_free`. */ -struct SPCommand *sp_command_brightness(uint8_t brightness); +SPCommand *sp_command_brightness(uint8_t brightness); /** * Set the brightness of individual tiles in a rectangular area of the display. @@ -1047,9 +1046,9 @@ struct SPCommand *sp_command_brightness(uint8_t brightness); * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_command_free`. */ -struct SPCommand *sp_command_char_brightness(size_t x, - size_t y, - struct SPBrightnessGrid *grid); +SPCommand *sp_command_char_brightness(size_t x, + size_t y, + SPBrightnessGrid *grid); /** * Set all pixels to the off state. @@ -1071,7 +1070,7 @@ struct SPCommand *sp_command_char_brightness(size_t x, * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_command_free`. */ -struct SPCommand *sp_command_clear(void); +SPCommand *sp_command_clear(void); /** * Clones a [SPCommand] instance. @@ -1091,7 +1090,7 @@ struct SPCommand *sp_command_clear(void); * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_command_free`. */ -struct SPCommand *sp_command_clone(const struct SPCommand *command); +SPCommand *sp_command_clone(const SPCommand *command); /** * Show text on the screen. @@ -1113,9 +1112,9 @@ struct SPCommand *sp_command_clone(const struct SPCommand *command); * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_command_free`. */ -struct SPCommand *sp_command_cp437_data(size_t x, - size_t y, - struct SPCp437Grid *grid); +SPCommand *sp_command_cp437_data(size_t x, + size_t y, + SPCp437Grid *grid); /** * A yet-to-be-tested command. @@ -1129,7 +1128,7 @@ struct SPCommand *sp_command_cp437_data(size_t x, * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_command_free`. */ -struct SPCommand *sp_command_fade_out(void); +SPCommand *sp_command_fade_out(void); /** * Deallocates a [SPCommand]. @@ -1153,7 +1152,7 @@ struct SPCommand *sp_command_fade_out(void); * - `command` is not used concurrently or after this call * - `command` was not passed to another consuming function, e.g. to create a [SPPacket] */ -void sp_command_free(struct SPCommand *command); +void sp_command_free(SPCommand *command); /** * Kills the udp daemon on the display, which usually results in a restart. @@ -1169,7 +1168,7 @@ void sp_command_free(struct SPCommand *command); * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_command_free`. */ -struct SPCommand *sp_command_hard_reset(void); +SPCommand *sp_command_hard_reset(void); /** * Tries to turn a [SPPacket] into a [SPCommand]. @@ -1192,7 +1191,7 @@ struct SPCommand *sp_command_hard_reset(void); * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_command_free`. */ -struct SPCommand *sp_command_try_from_packet(struct SPPacket *packet); +SPCommand *sp_command_try_from_packet(SPPacket *packet); /** * Closes and deallocates a [SPConnection]. @@ -1208,7 +1207,7 @@ struct SPCommand *sp_command_try_from_packet(struct SPPacket *packet); * - `connection` points to a valid [SPConnection] * - `connection` is not used concurrently or after this call */ -void sp_connection_free(struct SPConnection *connection); +void sp_connection_free(SPConnection *connection); /** * Creates a new instance of [SPConnection]. @@ -1226,7 +1225,7 @@ void sp_connection_free(struct SPConnection *connection); * - the returned instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_connection_free`. */ -struct SPConnection *sp_connection_open(const char *host); +SPConnection *sp_connection_open(const char *host); /** * Sends a [SPCommand] to the display using the [SPConnection]. @@ -1248,8 +1247,8 @@ struct SPConnection *sp_connection_open(const char *host); * - `command` points to a valid instance of [SPPacket] * - `command` is not used concurrently or after this call */ -bool sp_connection_send_command(const struct SPConnection *connection, - struct SPCommand *command); +bool sp_connection_send_command(const SPConnection *connection, + SPCommand *command); /** * Sends a [SPPacket] to the display using the [SPConnection]. @@ -1271,8 +1270,8 @@ bool sp_connection_send_command(const struct SPConnection *connection, * - `packet` points to a valid instance of [SPPacket] * - `packet` is not used concurrently or after this call */ -bool sp_connection_send_packet(const struct SPConnection *connection, - struct SPPacket *packet); +bool sp_connection_send_packet(const SPConnection *connection, + SPPacket *packet); /** * Clones a [SPCp437Grid]. @@ -1292,7 +1291,7 @@ bool sp_connection_send_packet(const struct SPConnection *connection, * - the returned instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_cp437_grid_free`. */ -struct SPCp437Grid *sp_cp437_grid_clone(const struct SPCp437Grid *cp437_grid); +SPCp437Grid *sp_cp437_grid_clone(const SPCp437Grid *cp437_grid); /** * Sets the value of all cells in the [SPCp437Grid]. @@ -1313,7 +1312,7 @@ struct SPCp437Grid *sp_cp437_grid_clone(const struct SPCp437Grid *cp437_grid); * - `cp437_grid` points to a valid [SPCp437Grid] * - `cp437_grid` is not written to or read from concurrently */ -void sp_cp437_grid_fill(struct SPCp437Grid *cp437_grid, uint8_t value); +void sp_cp437_grid_fill(SPCp437Grid *cp437_grid, uint8_t value); /** * Deallocates a [SPCp437Grid]. @@ -1330,7 +1329,7 @@ void sp_cp437_grid_fill(struct SPCp437Grid *cp437_grid, uint8_t value); * - `cp437_grid` is not used concurrently or after cp437_grid call * - `cp437_grid` was not passed to another consuming function, e.g. to create a [SPCommand] */ -void sp_cp437_grid_free(struct SPCp437Grid *cp437_grid); +void sp_cp437_grid_free(SPCp437Grid *cp437_grid); /** * Gets the current value at the specified position. @@ -1352,9 +1351,7 @@ void sp_cp437_grid_free(struct SPCp437Grid *cp437_grid); * - `cp437_grid` points to a valid [SPCp437Grid] * - `cp437_grid` is not written to concurrently */ -uint8_t sp_cp437_grid_get(const struct SPCp437Grid *cp437_grid, - size_t x, - size_t y); +uint8_t sp_cp437_grid_get(const SPCp437Grid *cp437_grid, size_t x, size_t y); /** * Gets the height of the [SPCp437Grid] instance. @@ -1373,7 +1370,7 @@ uint8_t sp_cp437_grid_get(const struct SPCp437Grid *cp437_grid, * * - `cp437_grid` points to a valid [SPCp437Grid] */ -size_t sp_cp437_grid_height(const struct SPCp437Grid *cp437_grid); +size_t sp_cp437_grid_height(const SPCp437Grid *cp437_grid); /** * Loads a [SPCp437Grid] with the specified dimensions from the provided data. @@ -1394,10 +1391,10 @@ size_t sp_cp437_grid_height(const struct SPCp437Grid *cp437_grid); * - the returned instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_cp437_grid_free`. */ -struct SPCp437Grid *sp_cp437_grid_load(size_t width, - size_t height, - const uint8_t *data, - size_t data_length); +SPCp437Grid *sp_cp437_grid_load(size_t width, + size_t height, + const uint8_t *data, + size_t data_length); /** * Creates a new [SPCp437Grid] with the specified dimensions. @@ -1411,8 +1408,8 @@ struct SPCp437Grid *sp_cp437_grid_load(size_t width, * - the returned instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_cp437_grid_free`. */ -struct SPCp437Grid *sp_cp437_grid_new(size_t width, - size_t height); +SPCp437Grid *sp_cp437_grid_new(size_t width, + size_t height); /** * Sets the value of the specified position in the [SPCp437Grid]. @@ -1437,7 +1434,7 @@ struct SPCp437Grid *sp_cp437_grid_new(size_t width, * - `cp437_grid` points to a valid [SPBitVec] * - `cp437_grid` is not written to or read from concurrently */ -void sp_cp437_grid_set(struct SPCp437Grid *cp437_grid, +void sp_cp437_grid_set(SPCp437Grid *cp437_grid, size_t x, size_t y, uint8_t value); @@ -1459,7 +1456,7 @@ void sp_cp437_grid_set(struct SPCp437Grid *cp437_grid, * - the returned memory range is never accessed after the passed [SPCp437Grid] has been freed * - the returned memory range is never accessed concurrently, either via the [SPCp437Grid] or directly */ -struct SPByteSlice sp_cp437_grid_unsafe_data_ref(struct SPCp437Grid *cp437_grid); +SPByteSlice sp_cp437_grid_unsafe_data_ref(SPCp437Grid *cp437_grid); /** * Gets the width of the [SPCp437Grid] instance. @@ -1478,7 +1475,7 @@ struct SPByteSlice sp_cp437_grid_unsafe_data_ref(struct SPCp437Grid *cp437_grid) * * - `cp437_grid` points to a valid [SPCp437Grid] */ -size_t sp_cp437_grid_width(const struct SPCp437Grid *cp437_grid); +size_t sp_cp437_grid_width(const SPCp437Grid *cp437_grid); /** * Clones a [SPPacket]. @@ -1498,7 +1495,7 @@ size_t sp_cp437_grid_width(const struct SPCp437Grid *cp437_grid); * - the returned instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_packet_free`. */ -struct SPPacket *sp_packet_clone(const struct SPPacket *packet); +SPPacket *sp_packet_clone(const SPPacket *packet); /** * Deallocates a [SPPacket]. @@ -1514,7 +1511,7 @@ struct SPPacket *sp_packet_clone(const struct SPPacket *packet); * - `packet` points to a valid [SPPacket] * - `packet` is not used concurrently or after this call */ -void sp_packet_free(struct SPPacket *packet); +void sp_packet_free(SPPacket *packet); /** * Turns a [SPCommand] into a [SPPacket]. @@ -1535,7 +1532,7 @@ void sp_packet_free(struct SPPacket *packet); * - the returned [SPPacket] instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_packet_free`. */ -struct SPPacket *sp_packet_from_command(struct SPCommand *command); +SPPacket *sp_packet_from_command(SPCommand *command); /** * Tries to load a [SPPacket] from the passed array with the specified length. @@ -1555,8 +1552,8 @@ struct SPPacket *sp_packet_from_command(struct SPCommand *command); * - the returned [SPPacket] instance is freed in some way, either by using a consuming function or * by explicitly calling `sp_packet_free`. */ -struct SPPacket *sp_packet_try_load(const uint8_t *data, - size_t length); +SPPacket *sp_packet_try_load(const uint8_t *data, + size_t length); #ifdef __cplusplus } // extern "C" From cbadd85f07ec732f0003c0000fbfb694e24e77a7 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 16 Oct 2024 19:21:45 +0200 Subject: [PATCH 24/27] use Origin::ZERO constant --- crates/servicepoint/examples/announce.rs | 2 +- crates/servicepoint/examples/brightness_tester.rs | 4 ++-- crates/servicepoint/examples/game_of_life.rs | 2 +- crates/servicepoint/examples/moving_line.rs | 2 +- crates/servicepoint/examples/random_brightness.rs | 2 +- crates/servicepoint/src/command.rs | 4 ++-- crates/servicepoint/src/compression_code.rs | 4 ++-- crates/servicepoint/src/lib.rs | 2 +- crates/servicepoint/src/origin.rs | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/crates/servicepoint/examples/announce.rs b/crates/servicepoint/examples/announce.rs index bb287b4..af78a54 100644 --- a/crates/servicepoint/examples/announce.rs +++ b/crates/servicepoint/examples/announce.rs @@ -46,6 +46,6 @@ fn main() { let cp437_grid = Cp437Grid::from(&grid); connection - .send(Command::Cp437Data(Origin::new(0, 0), cp437_grid)) + .send(Command::Cp437Data(Origin::ZERO, cp437_grid)) .expect("sending text failed"); } diff --git a/crates/servicepoint/examples/brightness_tester.rs b/crates/servicepoint/examples/brightness_tester.rs index 09e1ed6..8a31ee8 100644 --- a/crates/servicepoint/examples/brightness_tester.rs +++ b/crates/servicepoint/examples/brightness_tester.rs @@ -19,7 +19,7 @@ fn main() { pixels.fill(true); let command = Command::BitmapLinearWin( - Origin::new(0, 0), + Origin::ZERO, pixels, CompressionCode::Uncompressed, ); @@ -33,6 +33,6 @@ fn main() { } connection - .send(Command::CharBrightness(Origin::new(0, 0), brightnesses)) + .send(Command::CharBrightness(Origin::ZERO, brightnesses)) .expect("send failed"); } diff --git a/crates/servicepoint/examples/game_of_life.rs b/crates/servicepoint/examples/game_of_life.rs index 3a72f4e..76e8c70 100644 --- a/crates/servicepoint/examples/game_of_life.rs +++ b/crates/servicepoint/examples/game_of_life.rs @@ -24,7 +24,7 @@ fn main() { loop { let command = Command::BitmapLinearWin( - Origin::new(0, 0), + Origin::ZERO, field.clone(), CompressionCode::Lzma, ); diff --git a/crates/servicepoint/examples/moving_line.rs b/crates/servicepoint/examples/moving_line.rs index 3e55104..50cfcca 100644 --- a/crates/servicepoint/examples/moving_line.rs +++ b/crates/servicepoint/examples/moving_line.rs @@ -25,7 +25,7 @@ fn main() { } let command = Command::BitmapLinearWin( - Origin::new(0, 0), + Origin::ZERO, pixels.clone(), CompressionCode::Lzma, ); diff --git a/crates/servicepoint/examples/random_brightness.rs b/crates/servicepoint/examples/random_brightness.rs index 51ab515..f47cf72 100644 --- a/crates/servicepoint/examples/random_brightness.rs +++ b/crates/servicepoint/examples/random_brightness.rs @@ -32,7 +32,7 @@ fn main() { filled_grid.fill(true); let command = BitmapLinearWin( - Origin::new(0, 0), + Origin::ZERO, filled_grid, CompressionCode::Lzma, ); diff --git a/crates/servicepoint/src/command.rs b/crates/servicepoint/src/command.rs index 51235fd..eead79d 100644 --- a/crates/servicepoint/src/command.rs +++ b/crates/servicepoint/src/command.rs @@ -114,7 +114,7 @@ pub enum Command { /// /// // create command to send pixels /// let command = Command::BitmapLinearWin( - /// servicepoint::Origin::new(0, 0), + /// servicepoint::Origin::ZERO, /// pixels, /// CompressionCode::Uncompressed /// ); @@ -588,7 +588,7 @@ mod tests { compression, )); round_trip(Command::BitmapLinearWin( - Origin::new(0, 0), + Origin::ZERO, Bitmap::max_sized(), compression, )); diff --git a/crates/servicepoint/src/compression_code.rs b/crates/servicepoint/src/compression_code.rs index 25b0daf..d7db7cd 100644 --- a/crates/servicepoint/src/compression_code.rs +++ b/crates/servicepoint/src/compression_code.rs @@ -6,11 +6,11 @@ /// # use servicepoint::{Command, CompressionCode, Origin, Bitmap}; /// // create command without payload compression /// # let pixels = Bitmap::max_sized(); -/// _ = Command::BitmapLinearWin(Origin::new(0, 0), pixels, CompressionCode::Uncompressed); +/// _ = Command::BitmapLinearWin(Origin::ZERO, pixels, CompressionCode::Uncompressed); /// /// // create command with payload compressed with lzma and appropriate header flags /// # let pixels = Bitmap::max_sized(); -/// _ = Command::BitmapLinearWin(Origin::new(0, 0), pixels, CompressionCode::Lzma); +/// _ = Command::BitmapLinearWin(Origin::ZERO, pixels, CompressionCode::Lzma); /// ``` #[repr(u16)] #[derive(Debug, Clone, Copy, PartialEq)] diff --git a/crates/servicepoint/src/lib.rs b/crates/servicepoint/src/lib.rs index 3848967..94ac477 100644 --- a/crates/servicepoint/src/lib.rs +++ b/crates/servicepoint/src/lib.rs @@ -26,7 +26,7 @@ //! //! // create command to send pixels //! let command = Command::BitmapLinearWin( -//! servicepoint::Origin::new(0, 0), +//! servicepoint::Origin::ZERO, //! pixels, //! CompressionCode::Uncompressed //! ); diff --git a/crates/servicepoint/src/origin.rs b/crates/servicepoint/src/origin.rs index 6c0f5d2..345b89e 100644 --- a/crates/servicepoint/src/origin.rs +++ b/crates/servicepoint/src/origin.rs @@ -12,7 +12,7 @@ pub struct Origin { } impl Origin { - /// Top-left. Equivalent to `Origin::new(0, 0)`. + /// Top-left. Equivalent to `Origin::ZERO`. pub const ZERO: Self = Self { x: 0, y: 0, From ac6954322a3067233e34f5cdae006b4c98e95ba7 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 16 Oct 2024 20:02:06 +0200 Subject: [PATCH 25/27] fix constant types c# --- .../ServicePoint/Constants.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/servicepoint_binding_cs/ServicePoint/Constants.cs b/crates/servicepoint_binding_cs/ServicePoint/Constants.cs index fea5c55..14ea940 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/Constants.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/Constants.cs @@ -5,20 +5,20 @@ namespace ServicePoint; public static class Constants { /// size of a single tile in one dimension - public const int TileSize = NativeMethods.SP_TILE_SIZE; + public const nuint TileSize = NativeMethods.SP_TILE_SIZE; /// tile count in the x-direction - public const int TileWidth = NativeMethods.SP_TILE_WIDTH; + public const nuint TileWidth = NativeMethods.SP_TILE_WIDTH; /// tile count in the y-direction - public const int TileHeight = NativeMethods.SP_TILE_SIZE; + public const nuint TileHeight = NativeMethods.SP_TILE_SIZE; /// screen width in pixels - public const int PixelWidth = TileWidth * TileSize; + public const nuint PixelWidth = TileWidth * TileSize; /// screen height in pixels - public const int PixelHeight = TileHeight * TileSize; + public const nuint PixelHeight = TileHeight * TileSize; /// pixel count on whole screen - public const int PixelCount = PixelWidth * PixelHeight; + public const nuint PixelCount = PixelWidth * PixelHeight; } From 9193cfec10c72d99ad01b1ae09a935007588d7d9 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 16 Oct 2024 20:02:35 +0200 Subject: [PATCH 26/27] csbindgen seems change order all the time, maybe input ordering helps --- .../ServicePoint/BindGen/ServicePoint.g.cs | 1052 ++++++++--------- crates/servicepoint_binding_cs/build.rs | 8 +- 2 files changed, 532 insertions(+), 528 deletions(-) diff --git a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs b/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs index 2b5f14e..c8bb0a2 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs @@ -14,124 +14,261 @@ namespace ServicePoint.BindGen { const string __DllName = "servicepoint_binding_c"; - public const nuint SP_TILE_SIZE = 8; - public const nuint SP_TILE_WIDTH = 56; - public const nuint SP_TILE_HEIGHT = 20; public const byte SP_BRIGHTNESS_MIN = 0; public const byte SP_BRIGHTNESS_MAX = 11; public const byte SP_BRIGHTNESS_LEVELS = 12; + public const nuint SP_TILE_SIZE = 8; + public const nuint SP_TILE_WIDTH = 56; + public const nuint SP_TILE_HEIGHT = 20; /// - /// Creates a new instance of [SPConnection]. + /// Creates a new [SPBitmap] with the specified dimensions. /// - /// returns: NULL if connection fails, or connected instance + /// # Arguments + /// + /// - `width`: size in pixels in x-direction + /// - `height`: size in pixels in y-direction + /// + /// returns: [SPBitmap] initialized to all pixels off. Will never return NULL. /// /// # Panics /// - /// - when `host` is null or an invalid host + /// - when the width is not dividable by 8 /// /// # 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_connection_free`. + /// by explicitly calling `sp_bitmap_free`. /// - [DllImport(__DllName, EntryPoint = "sp_connection_open", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Connection* sp_connection_open(byte* host); + [DllImport(__DllName, EntryPoint = "sp_bitmap_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Bitmap* sp_bitmap_new(nuint width, nuint height); /// - /// Sends a [SPPacket] to the display using the [SPConnection]. + /// Loads a [SPBitmap] with the specified dimensions from the provided data. /// - /// The passed `packet` gets consumed. + /// # Arguments /// - /// returns: true in case of success + /// - `width`: size in pixels in x-direction + /// - `height`: size in pixels in y-direction + /// + /// returns: [SPBitmap] that contains a copy of the provided data. Will never return NULL. /// /// # Panics /// - /// - when `connection` is NULL - /// - when `packet` is NULL + /// - when `data` is NULL + /// - when the dimensions and data size do not match exactly. + /// - when the width is not dividable by 8 /// /// # Safety /// /// The caller has to make sure that: /// - /// - `connection` points to a valid instance of [SPConnection] - /// - `packet` points to a valid instance of [SPPacket] - /// - `packet` is not used concurrently or after this call + /// - `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_bitmap_free`. /// - [DllImport(__DllName, EntryPoint = "sp_connection_send_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_connection_send_packet(Connection* connection, Packet* packet); + [DllImport(__DllName, EntryPoint = "sp_bitmap_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Bitmap* sp_bitmap_load(nuint width, nuint height, byte* data, nuint data_length); /// - /// Sends a [SPCommand] to the display using the [SPConnection]. - /// - /// The passed `command` gets consumed. - /// - /// returns: true in case of success - /// - /// # Panics - /// - /// - when `connection` is NULL - /// - when `command` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `connection` points to a valid instance of [SPConnection] - /// - `command` points to a valid instance of [SPPacket] - /// - `command` is not used concurrently or after this call - /// - [DllImport(__DllName, EntryPoint = "sp_connection_send_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_connection_send_command(Connection* connection, Command* command); - - /// - /// Closes and deallocates a [SPConnection]. - /// - /// # Panics - /// - /// - when `connection` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `connection` points to a valid [SPConnection] - /// - `connection` is not used concurrently or after this call - /// - [DllImport(__DllName, EntryPoint = "sp_connection_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_connection_free(Connection* connection); - - /// - /// Turns a [SPCommand] into a [SPPacket]. - /// The [SPCommand] gets consumed. + /// Clones a [SPBitmap]. /// /// Will never return NULL. /// /// # Panics /// - /// - when `command` is NULL + /// - when `bitmap` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - [SPCommand] points to a valid instance of [SPCommand] - /// - [SPCommand] is not used concurrently or after this call - /// - the returned [SPPacket] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_packet_free`. + /// - `bitmap` points to a valid [SPBitmap] + /// - `bitmap` is not written to concurrently + /// - the returned instance is freed in some way, either by using a consuming function or + /// by explicitly calling `sp_bitmap_free`. /// - [DllImport(__DllName, EntryPoint = "sp_packet_from_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Packet* sp_packet_from_command(Command* command); + [DllImport(__DllName, EntryPoint = "sp_bitmap_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Bitmap* sp_bitmap_clone(Bitmap* bitmap); /// - /// Tries to load a [SPPacket] from the passed array with the specified length. + /// Deallocates a [SPBitmap]. /// - /// returns: NULL in case of an error, pointer to the allocated packet otherwise + /// # Panics + /// + /// - when `bitmap` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bitmap` points to a valid [SPBitmap] + /// - `bitmap` is not used concurrently or after bitmap call + /// - `bitmap` was not passed to another consuming function, e.g. to create a [SPCommand] + /// + [DllImport(__DllName, EntryPoint = "sp_bitmap_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bitmap_free(Bitmap* bitmap); + + /// + /// Gets the current value at the specified position in the [SPBitmap]. + /// + /// # Arguments + /// + /// - `bitmap`: instance to read from + /// - `x` and `y`: position of the cell to read + /// + /// # Panics + /// + /// - when `bitmap` is NULL + /// - when accessing `x` or `y` out of bounds + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bitmap` points to a valid [SPBitmap] + /// - `bitmap` is not written to concurrently + /// + [DllImport(__DllName, EntryPoint = "sp_bitmap_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.U1)] + public static extern bool sp_bitmap_get(Bitmap* bitmap, nuint x, nuint y); + + /// + /// Sets the value of the specified position in the [SPBitmap]. + /// + /// # Arguments + /// + /// - `bitmap`: 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 `bitmap` is NULL + /// - when accessing `x` or `y` out of bounds + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bitmap` points to a valid [SPBitmap] + /// - `bitmap` is not written to or read from concurrently + /// + [DllImport(__DllName, EntryPoint = "sp_bitmap_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bitmap_set(Bitmap* bitmap, nuint x, nuint y, [MarshalAs(UnmanagedType.U1)] bool value); + + /// + /// Sets the state of all pixels in the [SPBitmap]. + /// + /// # Arguments + /// + /// - `bitmap`: instance to write to + /// - `value`: the value to set all pixels to + /// + /// # Panics + /// + /// - when `bitmap` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bitmap` points to a valid [SPBitmap] + /// - `bitmap` is not written to or read from concurrently + /// + [DllImport(__DllName, EntryPoint = "sp_bitmap_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bitmap_fill(Bitmap* bitmap, [MarshalAs(UnmanagedType.U1)] bool value); + + /// + /// Gets the width in pixels of the [SPBitmap] instance. + /// + /// # Arguments + /// + /// - `bitmap`: instance to read from + /// + /// # Panics + /// + /// - when `bitmap` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bitmap` points to a valid [SPBitmap] + /// + [DllImport(__DllName, EntryPoint = "sp_bitmap_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern nuint sp_bitmap_width(Bitmap* bitmap); + + /// + /// Gets the height in pixels of the [SPBitmap] instance. + /// + /// # Arguments + /// + /// - `bitmap`: instance to read from + /// + /// # Panics + /// + /// - when `bitmap` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bitmap` points to a valid [SPBitmap] + /// + [DllImport(__DllName, EntryPoint = "sp_bitmap_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern nuint sp_bitmap_height(Bitmap* bitmap); + + /// + /// Gets an unsafe reference to the data of the [SPBitmap] instance. + /// + /// # Panics + /// + /// - when `bitmap` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bitmap` points to a valid [SPBitmap] + /// - the returned memory range is never accessed after the passed [SPBitmap] has been freed + /// - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly + /// + [DllImport(__DllName, EntryPoint = "sp_bitmap_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern ByteSlice sp_bitmap_unsafe_data_ref(Bitmap* bitmap); + + /// + /// Creates a new [SPBitVec] instance. + /// + /// # Arguments + /// + /// - `size`: size in bits. + /// + /// returns: [SPBitVec] with all bits set to false. Will never return NULL. + /// + /// # Panics + /// + /// - when `size` is not divisible by 8. + /// + /// # 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_bitvec_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_bitvec_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern BitVec* sp_bitvec_new(nuint size); + + /// + /// Interpret the data as a series of bits and load then into a new [SPBitVec] instance. + /// + /// returns: [SPBitVec] instance containing data. Will never return NULL. /// /// # Panics /// @@ -141,51 +278,187 @@ namespace ServicePoint.BindGen /// /// The caller has to make sure that: /// - /// - `data` points to a valid memory region of at least `length` bytes - /// - `data` is not written to concurrently - /// - the returned [SPPacket] instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_packet_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_packet_try_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Packet* sp_packet_try_load(byte* data, nuint length); - - /// - /// Clones a [SPPacket]. - /// - /// Will never return NULL. - /// - /// # Panics - /// - /// - when `packet` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `packet` points to a valid [SPPacket] - /// - `packet` is not written to concurrently + /// - `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_packet_free`. + /// by explicitly calling `sp_bitvec_free`. /// - [DllImport(__DllName, EntryPoint = "sp_packet_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Packet* sp_packet_clone(Packet* packet); + [DllImport(__DllName, EntryPoint = "sp_bitvec_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern BitVec* sp_bitvec_load(byte* data, nuint data_length); /// - /// Deallocates a [SPPacket]. + /// Clones a [SPBitVec]. + /// + /// returns: new [SPBitVec] instance. Will never return NULL. /// /// # Panics /// - /// - when `sp_packet_free` is NULL + /// - when `bit_vec` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `packet` points to a valid [SPPacket] - /// - `packet` is not used concurrently or after this call + /// - `bit_vec` points to a valid [SPBitVec] + /// - `bit_vec` is not written to concurrently + /// - the returned instance is freed in some way, either by using a consuming function or + /// by explicitly calling `sp_bitvec_free`. /// - [DllImport(__DllName, EntryPoint = "sp_packet_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_packet_free(Packet* packet); + [DllImport(__DllName, EntryPoint = "sp_bitvec_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern BitVec* sp_bitvec_clone(BitVec* bit_vec); + + /// + /// Deallocates a [SPBitVec]. + /// + /// # Panics + /// + /// - when `but_vec` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bit_vec` points to a valid [SPBitVec] + /// - `bit_vec` is not used concurrently or after this call + /// - `bit_vec` was not passed to another consuming function, e.g. to create a [SPCommand] + /// + [DllImport(__DllName, EntryPoint = "sp_bitvec_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bitvec_free(BitVec* bit_vec); + + /// + /// Gets the value of a bit from the [SPBitVec]. + /// + /// # Arguments + /// + /// - `bit_vec`: instance to read from + /// - `index`: the bit index to read + /// + /// returns: value of the bit + /// + /// # Panics + /// + /// - when `bit_vec` is NULL + /// - when accessing `index` out of bounds + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bit_vec` points to a valid [SPBitVec] + /// - `bit_vec` is not written to concurrently + /// + [DllImport(__DllName, EntryPoint = "sp_bitvec_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.U1)] + public static extern bool sp_bitvec_get(BitVec* bit_vec, nuint index); + + /// + /// Sets the value of a bit in the [SPBitVec]. + /// + /// # Arguments + /// + /// - `bit_vec`: instance to write to + /// - `index`: the bit index to edit + /// - `value`: the value to set the bit to + /// + /// # Panics + /// + /// - when `bit_vec` is NULL + /// - when accessing `index` out of bounds + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bit_vec` points to a valid [SPBitVec] + /// - `bit_vec` is not written to or read from concurrently + /// + [DllImport(__DllName, EntryPoint = "sp_bitvec_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bitvec_set(BitVec* bit_vec, nuint index, [MarshalAs(UnmanagedType.U1)] bool value); + + /// + /// Sets the value of all bits in the [SPBitVec]. + /// + /// # Arguments + /// + /// - `bit_vec`: instance to write to + /// - `value`: the value to set all bits to + /// + /// # Panics + /// + /// - when `bit_vec` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bit_vec` points to a valid [SPBitVec] + /// - `bit_vec` is not written to or read from concurrently + /// + [DllImport(__DllName, EntryPoint = "sp_bitvec_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bitvec_fill(BitVec* bit_vec, [MarshalAs(UnmanagedType.U1)] bool value); + + /// + /// Gets the length of the [SPBitVec] in bits. + /// + /// # Arguments + /// + /// - `bit_vec`: instance to write to + /// + /// # Panics + /// + /// - when `bit_vec` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bit_vec` points to a valid [SPBitVec] + /// + [DllImport(__DllName, EntryPoint = "sp_bitvec_len", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern nuint sp_bitvec_len(BitVec* bit_vec); + + /// + /// Returns true if length is 0. + /// + /// # Arguments + /// + /// - `bit_vec`: instance to write to + /// + /// # Panics + /// + /// - when `bit_vec` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `bit_vec` points to a valid [SPBitVec] + /// + [DllImport(__DllName, EntryPoint = "sp_bitvec_is_empty", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.U1)] + public static extern bool sp_bitvec_is_empty(BitVec* bit_vec); + + /// + /// Gets an unsafe reference to the data of the [SPBitVec] instance. + /// + /// # Arguments + /// + /// - `bit_vec`: instance to write to + /// + /// # Panics + /// + /// - when `bit_vec` is NULL + /// + /// ## Safety + /// + /// The caller has to make sure that: + /// + /// - `bit_vec` points to a valid [SPBitVec] + /// - the returned memory range is never accessed after the passed [SPBitVec] has been freed + /// - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly + /// + [DllImport(__DllName, EntryPoint = "sp_bitvec_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern ByteSlice sp_bitvec_unsafe_data_ref(BitVec* bit_vec); /// /// Creates a new [SPBrightnessGrid] with the specified dimensions. @@ -414,226 +687,6 @@ namespace ServicePoint.BindGen [DllImport(__DllName, EntryPoint = "sp_brightness_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern ByteSlice sp_brightness_grid_unsafe_data_ref(BrightnessGrid* brightness_grid); - /// - /// Creates a new [SPBitmap] with the specified dimensions. - /// - /// # Arguments - /// - /// - `width`: size in pixels in x-direction - /// - `height`: size in pixels in y-direction - /// - /// returns: [SPBitmap] initialized to all pixels off. Will never return NULL. - /// - /// # Panics - /// - /// - when the width is not dividable by 8 - /// - /// # 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_bitmap_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Bitmap* sp_bitmap_new(nuint width, nuint height); - - /// - /// Loads a [SPBitmap] with the specified dimensions from the provided data. - /// - /// # Arguments - /// - /// - `width`: size in pixels in x-direction - /// - `height`: size in pixels in y-direction - /// - /// returns: [SPBitmap] that contains a copy of the provided data. Will never return NULL. - /// - /// # Panics - /// - /// - when `data` is NULL - /// - when the dimensions and data size do not match exactly. - /// - when the width is not dividable by 8 - /// - /// # 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_bitmap_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Bitmap* sp_bitmap_load(nuint width, nuint height, byte* data, nuint data_length); - - /// - /// Clones a [SPBitmap]. - /// - /// Will never return NULL. - /// - /// # Panics - /// - /// - when `bitmap` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bitmap` points to a valid [SPBitmap] - /// - `bitmap` is not written to concurrently - /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_bitmap_free`. - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Bitmap* sp_bitmap_clone(Bitmap* bitmap); - - /// - /// Deallocates a [SPBitmap]. - /// - /// # Panics - /// - /// - when `bitmap` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bitmap` points to a valid [SPBitmap] - /// - `bitmap` is not used concurrently or after bitmap call - /// - `bitmap` was not passed to another consuming function, e.g. to create a [SPCommand] - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitmap_free(Bitmap* bitmap); - - /// - /// Gets the current value at the specified position in the [SPBitmap]. - /// - /// # Arguments - /// - /// - `bitmap`: instance to read from - /// - `x` and `y`: position of the cell to read - /// - /// # Panics - /// - /// - when `bitmap` is NULL - /// - when accessing `x` or `y` out of bounds - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bitmap` points to a valid [SPBitmap] - /// - `bitmap` is not written to concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_bitmap_get(Bitmap* bitmap, nuint x, nuint y); - - /// - /// Sets the value of the specified position in the [SPBitmap]. - /// - /// # Arguments - /// - /// - `bitmap`: 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 `bitmap` is NULL - /// - when accessing `x` or `y` out of bounds - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bitmap` points to a valid [SPBitmap] - /// - `bitmap` is not written to or read from concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitmap_set(Bitmap* bitmap, nuint x, nuint y, [MarshalAs(UnmanagedType.U1)] bool value); - - /// - /// Sets the state of all pixels in the [SPBitmap]. - /// - /// # Arguments - /// - /// - `bitmap`: instance to write to - /// - `value`: the value to set all pixels to - /// - /// # Panics - /// - /// - when `bitmap` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bitmap` points to a valid [SPBitmap] - /// - `bitmap` is not written to or read from concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitmap_fill(Bitmap* bitmap, [MarshalAs(UnmanagedType.U1)] bool value); - - /// - /// Gets the width in pixels of the [SPBitmap] instance. - /// - /// # Arguments - /// - /// - `bitmap`: instance to read from - /// - /// # Panics - /// - /// - when `bitmap` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bitmap` points to a valid [SPBitmap] - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_bitmap_width(Bitmap* bitmap); - - /// - /// Gets the height in pixels of the [SPBitmap] instance. - /// - /// # Arguments - /// - /// - `bitmap`: instance to read from - /// - /// # Panics - /// - /// - when `bitmap` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bitmap` points to a valid [SPBitmap] - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_bitmap_height(Bitmap* bitmap); - - /// - /// Gets an unsafe reference to the data of the [SPBitmap] instance. - /// - /// # Panics - /// - /// - when `bitmap` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bitmap` points to a valid [SPBitmap] - /// - the returned memory range is never accessed after the passed [SPBitmap] has been freed - /// - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly - /// - [DllImport(__DllName, EntryPoint = "sp_bitmap_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteSlice sp_bitmap_unsafe_data_ref(Bitmap* bitmap); - /// /// Tries to turn a [SPPacket] into a [SPCommand]. /// @@ -969,6 +1022,90 @@ namespace ServicePoint.BindGen [DllImport(__DllName, EntryPoint = "sp_command_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern void sp_command_free(Command* command); + /// + /// Creates a new instance of [SPConnection]. + /// + /// returns: NULL if connection fails, or connected instance + /// + /// # Panics + /// + /// - when `host` is null or an invalid host + /// + /// # 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_connection_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_connection_open", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Connection* sp_connection_open(byte* host); + + /// + /// Sends a [SPPacket] to the display using the [SPConnection]. + /// + /// The passed `packet` gets consumed. + /// + /// returns: true in case of success + /// + /// # Panics + /// + /// - when `connection` is NULL + /// - when `packet` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `connection` points to a valid instance of [SPConnection] + /// - `packet` points to a valid instance of [SPPacket] + /// - `packet` is not used concurrently or after this call + /// + [DllImport(__DllName, EntryPoint = "sp_connection_send_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.U1)] + public static extern bool sp_connection_send_packet(Connection* connection, Packet* packet); + + /// + /// Sends a [SPCommand] to the display using the [SPConnection]. + /// + /// The passed `command` gets consumed. + /// + /// returns: true in case of success + /// + /// # Panics + /// + /// - when `connection` is NULL + /// - when `command` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `connection` points to a valid instance of [SPConnection] + /// - `command` points to a valid instance of [SPPacket] + /// - `command` is not used concurrently or after this call + /// + [DllImport(__DllName, EntryPoint = "sp_connection_send_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.U1)] + public static extern bool sp_connection_send_command(Connection* connection, Command* command); + + /// + /// Closes and deallocates a [SPConnection]. + /// + /// # Panics + /// + /// - when `connection` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `connection` points to a valid [SPConnection] + /// - `connection` is not used concurrently or after this call + /// + [DllImport(__DllName, EntryPoint = "sp_connection_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_connection_free(Connection* connection); + /// /// Creates a new [SPCp437Grid] with the specified dimensions. /// @@ -1177,32 +1314,31 @@ namespace ServicePoint.BindGen public static extern ByteSlice sp_cp437_grid_unsafe_data_ref(Cp437Grid* cp437_grid); /// - /// Creates a new [SPBitVec] instance. + /// Turns a [SPCommand] into a [SPPacket]. + /// The [SPCommand] gets consumed. /// - /// # Arguments - /// - /// - `size`: size in bits. - /// - /// returns: [SPBitVec] with all bits set to false. Will never return NULL. + /// Will never return NULL. /// /// # Panics /// - /// - when `size` is not divisible by 8. + /// - when `command` is NULL /// /// # 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_bitvec_free`. + /// - [SPCommand] points to a valid instance of [SPCommand] + /// - [SPCommand] is not used concurrently or after this call + /// - the returned [SPPacket] instance is freed in some way, either by using a consuming function or + /// by explicitly calling `sp_packet_free`. /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BitVec* sp_bitvec_new(nuint size); + [DllImport(__DllName, EntryPoint = "sp_packet_from_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Packet* sp_packet_from_command(Command* command); /// - /// Interpret the data as a series of bits and load then into a new [SPBitVec] instance. + /// Tries to load a [SPPacket] from the passed array with the specified length. /// - /// returns: [SPBitVec] instance containing data. Will never return NULL. + /// returns: NULL in case of an error, pointer to the allocated packet otherwise /// /// # Panics /// @@ -1212,191 +1348,70 @@ namespace ServicePoint.BindGen /// /// The caller has to make sure that: /// - /// - `data` points to a valid memory location of at least `data_length` - /// bytes in size. + /// - `data` points to a valid memory region of at least `length` bytes + /// - `data` is not written to concurrently + /// - the returned [SPPacket] instance is freed in some way, either by using a consuming function or + /// by explicitly calling `sp_packet_free`. + /// + [DllImport(__DllName, EntryPoint = "sp_packet_try_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Packet* sp_packet_try_load(byte* data, nuint length); + + /// + /// Clones a [SPPacket]. + /// + /// Will never return NULL. + /// + /// # Panics + /// + /// - when `packet` is NULL + /// + /// # Safety + /// + /// The caller has to make sure that: + /// + /// - `packet` points to a valid [SPPacket] + /// - `packet` is not written to concurrently /// - 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_packet_free`. /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BitVec* sp_bitvec_load(byte* data, nuint data_length); + [DllImport(__DllName, EntryPoint = "sp_packet_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Packet* sp_packet_clone(Packet* packet); /// - /// Clones a [SPBitVec]. - /// - /// returns: new [SPBitVec] instance. Will never return NULL. + /// Deallocates a [SPPacket]. /// /// # Panics /// - /// - when `bit_vec` is NULL + /// - when `sp_packet_free` is NULL /// /// # Safety /// /// The caller has to make sure that: /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - `bit_vec` is not written to concurrently - /// - the returned instance is freed in some way, either by using a consuming function or - /// by explicitly calling `sp_bitvec_free`. + /// - `packet` points to a valid [SPPacket] + /// - `packet` is not used concurrently or after this call /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BitVec* sp_bitvec_clone(BitVec* bit_vec); - - /// - /// Deallocates a [SPBitVec]. - /// - /// # Panics - /// - /// - when `but_vec` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - `bit_vec` is not used concurrently or after this call - /// - `bit_vec` was not passed to another consuming function, e.g. to create a [SPCommand] - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitvec_free(BitVec* bit_vec); - - /// - /// Gets the value of a bit from the [SPBitVec]. - /// - /// # Arguments - /// - /// - `bit_vec`: instance to read from - /// - `index`: the bit index to read - /// - /// returns: value of the bit - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - when accessing `index` out of bounds - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - `bit_vec` is not written to concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_bitvec_get(BitVec* bit_vec, nuint index); - - /// - /// Sets the value of a bit in the [SPBitVec]. - /// - /// # Arguments - /// - /// - `bit_vec`: instance to write to - /// - `index`: the bit index to edit - /// - `value`: the value to set the bit to - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - when accessing `index` out of bounds - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - `bit_vec` is not written to or read from concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitvec_set(BitVec* bit_vec, nuint index, [MarshalAs(UnmanagedType.U1)] bool value); - - /// - /// Sets the value of all bits in the [SPBitVec]. - /// - /// # Arguments - /// - /// - `bit_vec`: instance to write to - /// - `value`: the value to set all bits to - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - `bit_vec` is not written to or read from concurrently - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitvec_fill(BitVec* bit_vec, [MarshalAs(UnmanagedType.U1)] bool value); - - /// - /// Gets the length of the [SPBitVec] in bits. - /// - /// # Arguments - /// - /// - `bit_vec`: instance to write to - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_len", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_bitvec_len(BitVec* bit_vec); - - /// - /// Returns true if length is 0. - /// - /// # Arguments - /// - /// - `bit_vec`: instance to write to - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - /// # Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_is_empty", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_bitvec_is_empty(BitVec* bit_vec); - - /// - /// Gets an unsafe reference to the data of the [SPBitVec] instance. - /// - /// # Arguments - /// - /// - `bit_vec`: instance to write to - /// - /// # Panics - /// - /// - when `bit_vec` is NULL - /// - /// ## Safety - /// - /// The caller has to make sure that: - /// - /// - `bit_vec` points to a valid [SPBitVec] - /// - the returned memory range is never accessed after the passed [SPBitVec] has been freed - /// - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly - /// - [DllImport(__DllName, EntryPoint = "sp_bitvec_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteSlice sp_bitvec_unsafe_data_ref(BitVec* bit_vec); + [DllImport(__DllName, EntryPoint = "sp_packet_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_packet_free(Packet* packet); } + [StructLayout(LayoutKind.Sequential)] + public unsafe partial struct Bitmap + { + } + + [StructLayout(LayoutKind.Sequential)] + public unsafe partial struct BitVec + { + } + + [StructLayout(LayoutKind.Sequential)] + public unsafe partial struct BrightnessGrid + { + } + [StructLayout(LayoutKind.Sequential)] public unsafe partial struct ByteSlice { @@ -1404,38 +1419,23 @@ namespace ServicePoint.BindGen public nuint length; } - [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct Connection - { - } - - [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct Packet - { - } - - [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct BrightnessGrid - { - } - - [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct Bitmap - { - } - [StructLayout(LayoutKind.Sequential)] public unsafe partial struct Command { } + [StructLayout(LayoutKind.Sequential)] + public unsafe partial struct Connection + { + } + [StructLayout(LayoutKind.Sequential)] public unsafe partial struct Cp437Grid { } [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct BitVec + public unsafe partial struct Packet { } diff --git a/crates/servicepoint_binding_cs/build.rs b/crates/servicepoint_binding_cs/build.rs index 5287698..8caf589 100644 --- a/crates/servicepoint_binding_cs/build.rs +++ b/crates/servicepoint_binding_cs/build.rs @@ -8,8 +8,12 @@ fn main() { let mut builder = csbindgen::Builder::default(); - for source in fs::read_dir("../servicepoint_binding_c/src").unwrap() { - let path = source.unwrap().path(); + let mut paths = fs::read_dir("../servicepoint_binding_c/src").unwrap() + .map(|x| x.unwrap().path()) + .collect::>(); + paths.sort(); + + for path in paths { println!("cargo:rerun-if-changed={}", path.display()); builder = builder.input_extern_file(path); } From 28f27204646c7a0d86f32b711c93a8dc44f46fa0 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 16 Oct 2024 20:07:52 +0200 Subject: [PATCH 27/27] Version 0.10.0 --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- crates/servicepoint/README.md | 2 +- crates/servicepoint_binding_c/Cargo.toml | 2 +- crates/servicepoint_binding_cs/Cargo.toml | 4 ++-- .../ServicePoint/ServicePoint.csproj | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 10ec770..5bc28b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -610,7 +610,7 @@ dependencies = [ [[package]] name = "servicepoint" -version = "0.9.1" +version = "0.10.0" dependencies = [ "bitvec", "bzip2", @@ -626,7 +626,7 @@ dependencies = [ [[package]] name = "servicepoint_binding_c" -version = "0.9.1" +version = "0.10.0" dependencies = [ "cbindgen", "servicepoint", @@ -634,7 +634,7 @@ dependencies = [ [[package]] name = "servicepoint_binding_cs" -version = "0.9.1" +version = "0.10.0" dependencies = [ "csbindgen", "servicepoint", diff --git a/Cargo.toml b/Cargo.toml index 8a6f9c9..6e534de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ members = [ ] [workspace.package] -version = "0.9.1" +version = "0.10.0" [workspace.lints.rust] missing-docs = "warn" diff --git a/crates/servicepoint/README.md b/crates/servicepoint/README.md index c7139da..303d29d 100644 --- a/crates/servicepoint/README.md +++ b/crates/servicepoint/README.md @@ -17,7 +17,7 @@ cargo add servicepoint or ```toml [dependencies] -servicepoint = "0.9.1" +servicepoint = "0.10.0" ``` ## Examples diff --git a/crates/servicepoint_binding_c/Cargo.toml b/crates/servicepoint_binding_c/Cargo.toml index 903a600..d8dd0a1 100644 --- a/crates/servicepoint_binding_c/Cargo.toml +++ b/crates/servicepoint_binding_c/Cargo.toml @@ -17,7 +17,7 @@ crate-type = ["staticlib", "cdylib", "rlib"] cbindgen = "0.27.0" [dependencies.servicepoint] -version = "0.9.1" +version = "0.10.0" path = "../servicepoint" features = ["all_compressions"] diff --git a/crates/servicepoint_binding_cs/Cargo.toml b/crates/servicepoint_binding_cs/Cargo.toml index 8333a21..caca7b9 100644 --- a/crates/servicepoint_binding_cs/Cargo.toml +++ b/crates/servicepoint_binding_cs/Cargo.toml @@ -13,8 +13,8 @@ test = false csbindgen = "1.9.3" [dependencies] -servicepoint_binding_c = { version = "0.9.1", path = "../servicepoint_binding_c" } -servicepoint = { version = "0.9.1", path = "../servicepoint" } +servicepoint_binding_c = { version = "0.10.0", path = "../servicepoint_binding_c" } +servicepoint = { version = "0.10.0", path = "../servicepoint" } [lints] workspace = true diff --git a/crates/servicepoint_binding_cs/ServicePoint/ServicePoint.csproj b/crates/servicepoint_binding_cs/ServicePoint/ServicePoint.csproj index c988f7d..0962c4c 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/ServicePoint.csproj +++ b/crates/servicepoint_binding_cs/ServicePoint/ServicePoint.csproj @@ -11,7 +11,7 @@ ServicePoint - 0.9.1 + 0.10.0 Repository Authors None ServicePoint