diff --git a/Cargo.lock b/Cargo.lock index 2dac4bc..55cb4e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -621,6 +621,7 @@ name = "servicepoint_binding_c" version = "0.4.2" dependencies = [ "cbindgen", + "servicepoint", ] [[package]] @@ -628,7 +629,7 @@ name = "servicepoint_binding_cs" version = "0.4.2" dependencies = [ "csbindgen", - "servicepoint", + "servicepoint_binding_c", ] [[package]] diff --git a/crates/servicepoint/Cargo.toml b/crates/servicepoint/Cargo.toml index 8e7fb65..9e0905b 100644 --- a/crates/servicepoint/Cargo.toml +++ b/crates/servicepoint/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/cccb/servicepoint" readme = "../../README.md" [lib] -crate-type = ["staticlib", "rlib", "cdylib"] +crate-type = ["rlib"] [dependencies] log = "0.4" @@ -20,10 +20,9 @@ zstd = { version = "0.13", optional = true } rust-lzma = { version = "0.6.0", optional = true } [features] -default = ["compression_lzma", "c_api"] +default = ["compression_lzma"] compression_zlib = ["dep:flate2"] compression_bzip2 = ["dep:bzip2"] compression_lzma = ["dep:rust-lzma"] compression_zstd = ["dep:zstd"] all_compressions = ["compression_zlib", "compression_bzip2", "compression_lzma", "compression_zstd"] -c_api = [] diff --git a/crates/servicepoint/src/bit_vec.rs b/crates/servicepoint/src/bit_vec.rs index a21ab4a..0f3e262 100644 --- a/crates/servicepoint/src/bit_vec.rs +++ b/crates/servicepoint/src/bit_vec.rs @@ -135,103 +135,6 @@ impl From<&[u8]> for BitVec { } } -#[cfg(feature = "c_api")] -pub mod c_api { - use crate::{BitVec, CByteSlice, DataRef}; - - /// Creates a new `BitVec` instance. - /// The returned instance has to be freed with `bit_vec_dealloc`. - #[no_mangle] - pub unsafe extern "C" fn sp2_bit_vec_new(size: usize) -> *mut BitVec { - Box::into_raw(Box::new(BitVec::new(size))) - } - - /// Loads a `BitVec` from the provided data. - /// The returned instance has to be freed with `bit_vec_dealloc`. - #[no_mangle] - pub unsafe extern "C" fn sp2_bit_vec_load( - data: *const u8, - data_length: usize, - ) -> *mut BitVec { - let data = std::slice::from_raw_parts(data, data_length); - Box::into_raw(Box::new(BitVec::from(data))) - } - - /// Clones a `BitVec`. - /// The returned instance has to be freed with `bit_vec_dealloc`. - #[no_mangle] - pub unsafe extern "C" fn sp2_bit_vec_clone( - this: *const BitVec, - ) -> *mut BitVec { - Box::into_raw(Box::new((*this).clone())) - } - - /// Deallocates a `BitVec`. - /// - /// Note: do not call this if the grid has been consumed in another way, e.g. to create a command. - #[no_mangle] - pub unsafe extern "C" fn sp2_bit_vec_dealloc(this: *mut BitVec) { - _ = Box::from_raw(this); - } - - /// Gets the value of a bit from the `BitVec`. - #[no_mangle] - pub unsafe extern "C" fn sp2_bit_vec_get( - this: *const BitVec, - index: usize, - ) -> bool { - (*this).get(index) - } - - /// Sets the value of a bit in the `BitVec`. - #[no_mangle] - pub unsafe extern "C" fn sp2_bit_vec_set( - this: *mut BitVec, - index: usize, - value: bool, - ) -> bool { - (*this).set(index, value) - } - - /// Sets the value of all bits in the `BitVec`. - #[no_mangle] - pub unsafe extern "C" fn sp2_bit_vec_fill(this: *mut BitVec, value: bool) { - (*this).fill(value) - } - - /// Gets the length of the `BitVec` in bits. - #[no_mangle] - pub unsafe extern "C" fn sp2_bit_vec_len(this: *const BitVec) -> usize { - (*this).len() - } - - /// Returns true if length is 0. - #[no_mangle] - pub unsafe extern "C" fn sp2_bit_vec_is_empty(this: *const BitVec) -> bool { - (*this).is_empty() - } - - /// Gets an unsafe reference to the data of the `BitVec` instance. - /// - /// ## Safety - /// - /// The caller has to make sure to never access the returned memory after the `BitVec` - /// instance has been consumed or manually deallocated. - /// - /// Reading and writing concurrently to either the original instance or the returned data will - /// result in undefined behavior. - #[no_mangle] - pub unsafe extern "C" fn sp2_bit_vec_unsafe_data_ref( - this: *mut BitVec, - ) -> CByteSlice { - let data = (*this).data_ref_mut(); - CByteSlice { - start: data.as_mut_ptr_range().start, - length: data.len(), - } - } -} - #[cfg(test)] mod tests { use crate::{BitVec, DataRef}; diff --git a/crates/servicepoint/src/byte_grid.rs b/crates/servicepoint/src/byte_grid.rs index 1fd0328..9a17ead 100644 --- a/crates/servicepoint/src/byte_grid.rs +++ b/crates/servicepoint/src/byte_grid.rs @@ -108,119 +108,6 @@ impl From for Vec { } } -#[cfg(feature = "c_api")] -pub mod c_api { - use crate::data_ref::DataRef; - use crate::grid::Grid; - use crate::{ByteGrid, CByteSlice}; - - /// Creates a new `ByteGrid` instance. - /// The returned instance has to be freed with `byte_grid_dealloc`. - #[no_mangle] - pub unsafe extern "C" fn sp2_byte_grid_new( - width: usize, - height: usize, - ) -> *mut ByteGrid { - Box::into_raw(Box::new(ByteGrid::new(width, height))) - } - - /// Loads a `ByteGrid` with the specified dimensions from the provided data. - /// The returned instance has to be freed with `byte_grid_dealloc`. - #[no_mangle] - pub unsafe extern "C" fn sp2_byte_grid_load( - width: usize, - height: usize, - data: *const u8, - data_length: usize, - ) -> *mut ByteGrid { - let data = std::slice::from_raw_parts(data, data_length); - Box::into_raw(Box::new(ByteGrid::load(width, height, data))) - } - - /// Clones a `ByteGrid`. - /// The returned instance has to be freed with `byte_grid_dealloc`. - #[no_mangle] - pub unsafe extern "C" fn sp2_byte_grid_clone( - this: *const ByteGrid, - ) -> *mut ByteGrid { - Box::into_raw(Box::new((*this).clone())) - } - - /// Deallocates a `ByteGrid`. - /// - /// Note: do not call this if the grid has been consumed in another way, e.g. to create a command. - #[no_mangle] - pub unsafe extern "C" fn sp2_byte_grid_dealloc(this: *mut ByteGrid) { - _ = Box::from_raw(this); - } - - /// Get the current value at the specified position - #[no_mangle] - pub unsafe extern "C" fn sp2_byte_grid_get( - this: *const ByteGrid, - x: usize, - y: usize, - ) -> u8 { - (*this).get(x, y) - } - - /// Sets the current value at the specified position - #[no_mangle] - pub unsafe extern "C" fn sp2_byte_grid_set( - this: *mut ByteGrid, - x: usize, - y: usize, - value: u8, - ) { - (*this).set(x, y, value); - } - - /// Fills the whole `ByteGrid` with the specified value - #[no_mangle] - pub unsafe extern "C" fn sp2_byte_grid_fill( - this: *mut ByteGrid, - value: u8, - ) { - (*this).fill(value); - } - - /// Gets the width in pixels of the `ByteGrid` instance. - #[no_mangle] - pub unsafe extern "C" fn sp2_byte_grid_width( - this: *const ByteGrid, - ) -> usize { - (*this).width - } - - /// Gets the height in pixels of the `ByteGrid` instance. - #[no_mangle] - pub unsafe extern "C" fn sp2_byte_grid_height( - this: *const ByteGrid, - ) -> usize { - (*this).height - } - - /// Gets an unsafe reference to the data of the `ByteGrid` instance. - /// - /// ## Safety - /// - /// The caller has to make sure to never access the returned memory after the `ByteGrid` - /// instance has been consumed or manually deallocated. - /// - /// Reading and writing concurrently to either the original instance or the returned data will - /// result in undefined behavior. - #[no_mangle] - pub unsafe extern "C" fn sp2_byte_grid_unsafe_data_ref( - this: *mut ByteGrid, - ) -> CByteSlice { - let data = (*this).data_ref_mut(); - CByteSlice { - start: data.as_mut_ptr_range().start, - length: data.len(), - } - } -} - #[cfg(test)] mod tests { use crate::{ByteGrid, DataRef, Grid}; diff --git a/crates/servicepoint/src/command.rs b/crates/servicepoint/src/command.rs index de6a492..4e653eb 100644 --- a/crates/servicepoint/src/command.rs +++ b/crates/servicepoint/src/command.rs @@ -391,179 +391,6 @@ impl Command { } } -#[cfg(feature = "c_api")] -pub mod c_api { - use std::ptr::null_mut; - - use crate::{ - BitVec, Brightness, ByteGrid, Command, CompressionCode, Offset, Origin, - Packet, PixelGrid, - }; - - /// Tries to turn a `Packet` into a `Command`. The packet is gets deallocated in the process. - /// - /// Returns: pointer to command or NULL - #[no_mangle] - pub unsafe extern "C" fn sp2_command_try_from_packet( - packet: *mut Packet, - ) -> *mut Command { - let packet = *Box::from_raw(packet); - match Command::try_from(packet) { - Err(_) => null_mut(), - Ok(command) => Box::into_raw(Box::new(command)), - } - } - - /// Clones a `Command` instance - #[no_mangle] - pub unsafe extern "C" fn sp2_command_clone( - original: *const Command, - ) -> *mut Command { - Box::into_raw(Box::new((*original).clone())) - } - - /// Allocates a new `Command::Clear` instance - #[no_mangle] - pub unsafe extern "C" fn sp2_command_clear() -> *mut Command { - Box::into_raw(Box::new(Command::Clear)) - } - - /// Allocates a new `Command::HardReset` instance - #[no_mangle] - pub unsafe extern "C" fn sp2_command_hard_reset() -> *mut Command { - Box::into_raw(Box::new(Command::HardReset)) - } - - /// Allocates a new `Command::FadeOut` instance - #[no_mangle] - pub unsafe extern "C" fn sp2_command_fade_out() -> *mut Command { - Box::into_raw(Box::new(Command::FadeOut)) - } - - /// Allocates a new `Command::Brightness` instance - #[no_mangle] - pub unsafe extern "C" fn sp2_command_brightness( - brightness: Brightness, - ) -> *mut Command { - Box::into_raw(Box::new(Command::Brightness(brightness))) - } - - /// Allocates a new `Command::CharBrightness` instance. - /// The passed `ByteGrid` gets deallocated in the process. - #[no_mangle] - pub unsafe extern "C" fn sp2_command_char_brightness( - x: usize, - y: usize, - byte_grid: *mut ByteGrid, - ) -> *mut Command { - let byte_grid = *Box::from_raw(byte_grid); - Box::into_raw(Box::new(Command::CharBrightness( - Origin(x, y), - byte_grid, - ))) - } - - /// Allocates a new `Command::BitmapLinear` instance. - /// The passed `BitVec` gets deallocated in the process. - #[no_mangle] - pub unsafe extern "C" fn sp2_command_bitmap_linear( - offset: Offset, - bit_vec: *mut BitVec, - compression: CompressionCode, - ) -> *mut Command { - let bit_vec = *Box::from_raw(bit_vec); - Box::into_raw(Box::new(Command::BitmapLinear( - offset, - bit_vec, - compression, - ))) - } - - /// Allocates a new `Command::BitmapLinearAnd` instance. - /// The passed `BitVec` gets deallocated in the process. - #[no_mangle] - pub unsafe extern "C" fn sp2_command_bitmap_linear_and( - offset: Offset, - bit_vec: *mut BitVec, - compression: CompressionCode, - ) -> *mut Command { - let bit_vec = *Box::from_raw(bit_vec); - Box::into_raw(Box::new(Command::BitmapLinearAnd( - offset, - bit_vec, - compression, - ))) - } - - /// Allocates a new `Command::BitmapLinearOr` instance. - /// The passed `BitVec` gets deallocated in the process. - #[no_mangle] - pub unsafe extern "C" fn sp2_command_bitmap_linear_or( - offset: Offset, - bit_vec: *mut BitVec, - compression: CompressionCode, - ) -> *mut Command { - let bit_vec = *Box::from_raw(bit_vec); - Box::into_raw(Box::new(Command::BitmapLinearOr( - offset, - bit_vec, - compression, - ))) - } - - /// Allocates a new `Command::BitmapLinearXor` instance. - /// The passed `BitVec` gets deallocated in the process. - #[no_mangle] - pub unsafe extern "C" fn sp2_command_bitmap_linear_xor( - offset: Offset, - bit_vec: *mut BitVec, - compression: CompressionCode, - ) -> *mut Command { - let bit_vec = *Box::from_raw(bit_vec); - Box::into_raw(Box::new(Command::BitmapLinearXor( - offset, - bit_vec, - compression, - ))) - } - - /// Allocates a new `Command::Cp437Data` instance. - /// The passed `ByteGrid` gets deallocated in the process. - #[no_mangle] - pub unsafe extern "C" fn sp2_command_cp437_data( - x: usize, - y: usize, - byte_grid: *mut ByteGrid, - ) -> *mut Command { - let byte_grid = *Box::from_raw(byte_grid); - Box::into_raw(Box::new(Command::Cp437Data(Origin(x, y), byte_grid))) - } - - /// Allocates a new `Command::BitmapLinearWin` instance. - /// The passed `PixelGrid` gets deallocated in the process. - #[no_mangle] - pub unsafe extern "C" fn sp2_command_bitmap_linear_win( - x: usize, - y: usize, - byte_grid: *mut PixelGrid, - compression_code: CompressionCode, - ) -> *mut Command { - let byte_grid = *Box::from_raw(byte_grid); - Box::into_raw(Box::new(Command::BitmapLinearWin( - Origin(x, y), - byte_grid, - compression_code, - ))) - } - - /// Deallocates a `Command`. Note that connection_send does this implicitly, so you only need - /// to do this if you use the library for parsing commands. - #[no_mangle] - pub unsafe extern "C" fn sp2_command_dealloc(ptr: *mut Command) { - _ = Box::from_raw(ptr); - } -} - #[cfg(test)] mod tests { use crate::command::TryFromPacketError; diff --git a/crates/servicepoint/src/connection.rs b/crates/servicepoint/src/connection.rs index 099e379..356f97a 100644 --- a/crates/servicepoint/src/connection.rs +++ b/crates/servicepoint/src/connection.rs @@ -10,8 +10,6 @@ pub struct Connection { socket: UdpSocket, } - - impl Connection { /// Open a new UDP socket and connect to the provided host. /// @@ -64,7 +62,10 @@ impl Connection { /// connection.send(Command::BitmapLinearWin(servicepoint::Origin(0, 0), pixels, CompressionCode::Uncompressed)) /// .expect("send failed"); /// ``` - pub fn send(&self, packet: impl Into) -> Result<(), std::io::Error> { + pub fn send( + &self, + packet: impl Into, + ) -> Result<(), std::io::Error> { let packet = packet.into(); debug!("sending {packet:?}"); let data: Vec = packet.into(); @@ -72,46 +73,3 @@ impl Connection { Ok(()) } } - -#[cfg(feature = "c_api")] -pub mod c_api { - use std::ffi::{c_char, CStr}; - use std::ptr::null_mut; - - use crate::{Connection, Packet}; - - /// Creates a new instance of Connection. - /// The returned instance has to be deallocated with `connection_dealloc`. - /// - /// returns: NULL if connection fails or connected instance - /// - /// Panics: bad string encoding - #[no_mangle] - pub unsafe extern "C" fn sp2_connection_open( - host: *const c_char, - ) -> *mut Connection { - let host = CStr::from_ptr(host).to_str().expect("Bad encoding"); - let connection = match Connection::open(host) { - Err(_) => return null_mut(), - Ok(value) => value, - }; - - Box::into_raw(Box::new(connection)) - } - - /// Sends the command instance. The instance is consumed / destroyed and cannot be used after this call. - #[no_mangle] - pub unsafe extern "C" fn sp2_connection_send( - connection: *const Connection, - command_ptr: *mut Packet, - ) -> bool { - let packet = Box::from_raw(command_ptr); - (*connection).send(*packet).is_ok() - } - - /// Closes and deallocates a connection instance - #[no_mangle] - pub unsafe extern "C" fn sp2_connection_dealloc(ptr: *mut Connection) { - _ = Box::from_raw(ptr); - } -} diff --git a/crates/servicepoint/src/lib.rs b/crates/servicepoint/src/lib.rs index a3b5b7a..5b3bcea 100644 --- a/crates/servicepoint/src/lib.rs +++ b/crates/servicepoint/src/lib.rs @@ -2,8 +2,6 @@ use std::time::Duration; pub use crate::bit_vec::BitVec; pub use crate::byte_grid::ByteGrid; -#[cfg(feature = "c_api")] -pub use crate::c_slice::CByteSlice; pub use crate::command::{Brightness, Command, Offset, Origin}; pub use crate::compression_code::CompressionCode; pub use crate::connection::Connection; @@ -14,7 +12,6 @@ pub use crate::pixel_grid::PixelGrid; mod bit_vec; mod byte_grid; -mod c_slice; mod command; mod command_code; mod compression; diff --git a/crates/servicepoint/src/packet.rs b/crates/servicepoint/src/packet.rs index 11c0c03..d6cb78b 100644 --- a/crates/servicepoint/src/packet.rs +++ b/crates/servicepoint/src/packet.rs @@ -58,46 +58,6 @@ impl TryFrom<&[u8]> for Packet { } } -#[cfg(feature = "c_api")] -mod c_api { - use std::ptr::null_mut; - - use crate::{Command, Packet}; - - /// Turns a `Command` into a `Packet`. The command gets deallocated in the process. - #[no_mangle] - pub unsafe extern "C" fn sp2_packet_from_command( - command: *mut Command, - ) -> *mut Packet { - let command = *Box::from_raw(command); - let packet = command.into(); - Box::into_raw(Box::new(packet)) - } - - /// Tries to load a `Packet` from the passed array with the specified length. - /// - /// returns: NULL in case of an error, pointer to the allocated packet otherwise - #[no_mangle] - pub unsafe extern "C" fn sp2_packet_try_load( - data: *const u8, - length: usize, - ) -> *mut Packet { - let data = std::slice::from_raw_parts(data, length); - match Packet::try_from(data) { - Err(_) => null_mut(), - Ok(packet) => Box::into_raw(Box::new(packet)), - } - } - - /// Deallocates a `Packet`. - /// - /// Note: do not call this if the instance has been consumed in another way, e.g. by sending it. - #[no_mangle] - pub unsafe extern "C" fn sp2_packet_dealloc(this: *mut Packet) { - _ = Box::from_raw(this) - } -} - #[cfg(test)] mod tests { use crate::{Header, Packet}; diff --git a/crates/servicepoint/src/pixel_grid.rs b/crates/servicepoint/src/pixel_grid.rs index 3c19942..bead3da 100644 --- a/crates/servicepoint/src/pixel_grid.rs +++ b/crates/servicepoint/src/pixel_grid.rs @@ -127,118 +127,6 @@ impl From for Vec { } } -#[cfg(feature = "c_api")] -pub mod c_api { - use crate::c_slice::CByteSlice; - use crate::{DataRef, Grid, PixelGrid}; - - /// Creates a new `PixelGrid` instance. - /// The returned instance has to be freed with `pixel_grid_dealloc`. - #[no_mangle] - pub unsafe extern "C" fn sp2_pixel_grid_new( - width: usize, - height: usize, - ) -> *mut PixelGrid { - Box::into_raw(Box::new(PixelGrid::new(width, height))) - } - - /// Loads a `PixelGrid` with the specified dimensions from the provided data. - /// The returned instance has to be freed with `pixel_grid_dealloc`. - #[no_mangle] - pub unsafe extern "C" fn sp2_pixel_grid_load( - width: usize, - height: usize, - data: *const u8, - data_length: usize, - ) -> *mut PixelGrid { - let data = std::slice::from_raw_parts(data, data_length); - Box::into_raw(Box::new(PixelGrid::load(width, height, data))) - } - - /// Clones a `PixelGrid`. - /// The returned instance has to be freed with `pixel_grid_dealloc`. - #[no_mangle] - pub unsafe extern "C" fn sp2_pixel_grid_clone( - this: *const PixelGrid, - ) -> *mut PixelGrid { - Box::into_raw(Box::new((*this).clone())) - } - - /// Deallocates a `PixelGrid`. - /// - /// Note: do not call this if the grid has been consumed in another way, e.g. to create a command. - #[no_mangle] - pub unsafe extern "C" fn sp2_pixel_grid_dealloc(this: *mut PixelGrid) { - _ = Box::from_raw(this); - } - - /// Get the current value at the specified position - #[no_mangle] - pub unsafe extern "C" fn sp2_pixel_grid_get( - this: *const PixelGrid, - x: usize, - y: usize, - ) -> bool { - (*this).get(x, y) - } - - /// Sets the current value at the specified position - #[no_mangle] - pub unsafe extern "C" fn sp2_pixel_grid_set( - this: *mut PixelGrid, - x: usize, - y: usize, - value: bool, - ) { - (*this).set(x, y, value); - } - - /// Fills the whole `PixelGrid` with the specified value - #[no_mangle] - pub unsafe extern "C" fn sp2_pixel_grid_fill( - this: *mut PixelGrid, - value: bool, - ) { - (*this).fill(value); - } - - /// Gets the width in pixels of the `PixelGrid` instance. - #[no_mangle] - pub unsafe extern "C" fn sp2_pixel_grid_width( - this: *const PixelGrid, - ) -> usize { - (*this).width - } - - /// Gets the height in pixels of the `PixelGrid` instance. - #[no_mangle] - pub unsafe extern "C" fn sp2_pixel_grid_height( - this: *const PixelGrid, - ) -> usize { - (*this).height - } - - /// Gets an unsafe reference to the data of the `PixelGrid` instance. - /// - /// ## Safety - /// - /// The caller has to make sure to never access the returned memory after the `PixelGrid` - /// instance has been consumed or manually deallocated. - /// - /// Reading and writing concurrently to either the original instance or the returned data will - /// result in undefined behavior. - #[no_mangle] - pub unsafe extern "C" fn sp2_pixel_grid_unsafe_data_ref( - this: *mut PixelGrid, - ) -> CByteSlice { - let data = (*this).data_ref_mut(); - CByteSlice { - start: data.as_mut_ptr_range().start, - length: data.len(), - } - } -} - #[cfg(test)] mod tests { use crate::{DataRef, Grid, PixelGrid}; diff --git a/crates/servicepoint_binding_c/Cargo.toml b/crates/servicepoint_binding_c/Cargo.toml index 9a2cb27..d47ccde 100644 --- a/crates/servicepoint_binding_c/Cargo.toml +++ b/crates/servicepoint_binding_c/Cargo.toml @@ -10,5 +10,13 @@ repository = "https://github.com/cccb/servicepoint" readme = "../../README.md" links = "servicepoint" +[lib] +crate-type = ["staticlib", "cdylib", "rlib"] + [build-dependencies] cbindgen = "0.26.0" + +[dependencies.servicepoint] +version = "0.4.2" +path = "../servicepoint" +features = ["all_compressions"] diff --git a/crates/servicepoint_binding_c/build.rs b/crates/servicepoint_binding_c/build.rs index f5e4607..10505b0 100644 --- a/crates/servicepoint_binding_c/build.rs +++ b/crates/servicepoint_binding_c/build.rs @@ -8,12 +8,11 @@ fn main() { let config = Config::from_file(crate_dir.clone() + "/cbindgen.toml").unwrap(); - let servicepoint_dir = crate_dir.clone() + "/../servicepoint"; let output_dir = env::var("OUT_DIR").unwrap(); let header_file = output_dir.clone() + "/servicepoint.h"; - generate_with_config(servicepoint_dir, config) + generate_with_config(crate_dir, config) .unwrap() .write_to_file(&header_file); println!("cargo:include={output_dir}"); diff --git a/crates/servicepoint_binding_c/cbindgen.toml b/crates/servicepoint_binding_c/cbindgen.toml index 42d7d04..1c63d58 100644 --- a/crates/servicepoint_binding_c/cbindgen.toml +++ b/crates/servicepoint_binding_c/cbindgen.toml @@ -19,17 +19,18 @@ sort_by = "Name" usize_is_size_t = true [defines] -"feature = compression_zlib" = "SP2_FEATURE_compression_zlib" -"feature = compression_bzip2" = "SP2_FEATURE_compression_bzip2" -"feature = compression_lzma" = "SP2_FEATURE_compression_lzma" -"feature = compression_zstd" = "SP2_FEATURE_compression_zstd" +#"feature = compression_zlib" = "SP_FEATURE_compression_zlib" +#"feature = compression_bzip2" = "SP_FEATURE_compression_bzip2" +#"feature = compression_lzma" = "SP_FEATURE_compression_lzma" +#"feature = compression_zstd" = "SP_FEATURE_compression_zstd" [export] -prefix = "sp2_" +prefix = "sp_" [parse] -#include = ["servicepoint"] +parse_deps = true +include = ["servicepoint"] +extra_bindings = ["servicepoint"] [parse.expand] -features = ["c-api"] -all_features = true +#all_features = true diff --git a/crates/servicepoint_binding_c/src/bit_vec.rs b/crates/servicepoint_binding_c/src/bit_vec.rs new file mode 100644 index 0000000..dfeb5d4 --- /dev/null +++ b/crates/servicepoint_binding_c/src/bit_vec.rs @@ -0,0 +1,94 @@ +pub use servicepoint::BitVec; +use servicepoint::DataRef; + +use crate::c_slice::CByteSlice; + +/// Creates a new `BitVec` instance. +/// The returned instance has to be freed with `bit_vec_dealloc`. +#[no_mangle] +pub unsafe extern "C" fn sp_bit_vec_new(size: usize) -> *mut BitVec { + Box::into_raw(Box::new(BitVec::new(size))) +} + +/// Loads a `BitVec` from the provided data. +/// The returned instance has to be freed with `bit_vec_dealloc`. +#[no_mangle] +pub unsafe extern "C" fn sp_bit_vec_load( + data: *const u8, + data_length: usize, +) -> *mut BitVec { + let data = std::slice::from_raw_parts(data, data_length); + Box::into_raw(Box::new(BitVec::from(data))) +} + +/// Clones a `BitVec`. +/// The returned instance has to be freed with `bit_vec_dealloc`. +#[no_mangle] +pub unsafe extern "C" fn sp_bit_vec_clone(this: *const BitVec) -> *mut BitVec { + Box::into_raw(Box::new((*this).clone())) +} + +/// Deallocates a `BitVec`. +/// +/// Note: do not call this if the grid has been consumed in another way, e.g. to create a command. +#[no_mangle] +pub unsafe extern "C" fn sp_bit_vec_dealloc(this: *mut BitVec) { + _ = Box::from_raw(this); +} + +/// Gets the value of a bit from the `BitVec`. +#[no_mangle] +pub unsafe extern "C" fn sp_bit_vec_get( + this: *const BitVec, + index: usize, +) -> bool { + (*this).get(index) +} + +/// Sets the value of a bit in the `BitVec`. +#[no_mangle] +pub unsafe extern "C" fn sp_bit_vec_set( + this: *mut BitVec, + index: usize, + value: bool, +) -> bool { + (*this).set(index, value) +} + +/// Sets the value of all bits in the `BitVec`. +#[no_mangle] +pub unsafe extern "C" fn sp_bit_vec_fill(this: *mut BitVec, value: bool) { + (*this).fill(value) +} + +/// Gets the length of the `BitVec` in bits. +#[no_mangle] +pub unsafe extern "C" fn sp_bit_vec_len(this: *const BitVec) -> usize { + (*this).len() +} + +/// Returns true if length is 0. +#[no_mangle] +pub unsafe extern "C" fn sp_bit_vec_is_empty(this: *const BitVec) -> bool { + (*this).is_empty() +} + +/// Gets an unsafe reference to the data of the `BitVec` instance. +/// +/// ## Safety +/// +/// The caller has to make sure to never access the returned memory after the `BitVec` +/// instance has been consumed or manually deallocated. +/// +/// Reading and writing concurrently to either the original instance or the returned data will +/// result in undefined behavior. +#[no_mangle] +pub unsafe extern "C" fn sp_bit_vec_unsafe_data_ref( + this: *mut BitVec, +) -> CByteSlice { + let data = (*this).data_ref_mut(); + CByteSlice { + start: data.as_mut_ptr_range().start, + length: data.len(), + } +} diff --git a/crates/servicepoint_binding_c/src/byte_grid.rs b/crates/servicepoint_binding_c/src/byte_grid.rs new file mode 100644 index 0000000..124420f --- /dev/null +++ b/crates/servicepoint_binding_c/src/byte_grid.rs @@ -0,0 +1,103 @@ +pub use servicepoint::ByteGrid; +use servicepoint::{DataRef, Grid}; + +use crate::c_slice::CByteSlice; + +/// Creates a new `ByteGrid` instance. +/// The returned instance has to be freed with `byte_grid_dealloc`. +#[no_mangle] +pub unsafe extern "C" fn sp_byte_grid_new( + width: usize, + height: usize, +) -> *mut ByteGrid { + Box::into_raw(Box::new(ByteGrid::new(width, height))) +} + +/// Loads a `ByteGrid` with the specified dimensions from the provided data. +/// The returned instance has to be freed with `byte_grid_dealloc`. +#[no_mangle] +pub unsafe extern "C" fn sp_byte_grid_load( + width: usize, + height: usize, + data: *const u8, + data_length: usize, +) -> *mut ByteGrid { + let data = std::slice::from_raw_parts(data, data_length); + Box::into_raw(Box::new(ByteGrid::load(width, height, data))) +} + +/// Clones a `ByteGrid`. +/// The returned instance has to be freed with `byte_grid_dealloc`. +#[no_mangle] +pub unsafe extern "C" fn sp_byte_grid_clone( + this: *const ByteGrid, +) -> *mut ByteGrid { + Box::into_raw(Box::new((*this).clone())) +} + +/// Deallocates a `ByteGrid`. +/// +/// Note: do not call this if the grid has been consumed in another way, e.g. to create a command. +#[no_mangle] +pub unsafe extern "C" fn sp_byte_grid_dealloc(this: *mut ByteGrid) { + _ = Box::from_raw(this); +} + +/// Get the current value at the specified position +#[no_mangle] +pub unsafe extern "C" fn sp_byte_grid_get( + this: *const ByteGrid, + x: usize, + y: usize, +) -> u8 { + (*this).get(x, y) +} + +/// Sets the current value at the specified position +#[no_mangle] +pub unsafe extern "C" fn sp_byte_grid_set( + this: *mut ByteGrid, + x: usize, + y: usize, + value: u8, +) { + (*this).set(x, y, value); +} + +/// Fills the whole `ByteGrid` with the specified value +#[no_mangle] +pub unsafe extern "C" fn sp_byte_grid_fill(this: *mut ByteGrid, value: u8) { + (*this).fill(value); +} + +/// Gets the width in pixels of the `ByteGrid` instance. +#[no_mangle] +pub unsafe extern "C" fn sp_byte_grid_width(this: *const ByteGrid) -> usize { + (*this).width() +} + +/// Gets the height in pixels of the `ByteGrid` instance. +#[no_mangle] +pub unsafe extern "C" fn sp_byte_grid_height(this: *const ByteGrid) -> usize { + (*this).height() +} + +/// Gets an unsafe reference to the data of the `ByteGrid` instance. +/// +/// ## Safety +/// +/// The caller has to make sure to never access the returned memory after the `ByteGrid` +/// instance has been consumed or manually deallocated. +/// +/// Reading and writing concurrently to either the original instance or the returned data will +/// result in undefined behavior. +#[no_mangle] +pub unsafe extern "C" fn sp_byte_grid_unsafe_data_ref( + this: *mut ByteGrid, +) -> CByteSlice { + let data = (*this).data_ref_mut(); + CByteSlice { + start: data.as_mut_ptr_range().start, + length: data.len(), + } +} diff --git a/crates/servicepoint/src/c_slice.rs b/crates/servicepoint_binding_c/src/c_slice.rs similarity index 91% rename from crates/servicepoint/src/c_slice.rs rename to crates/servicepoint_binding_c/src/c_slice.rs index 5ee71f6..9609906 100644 --- a/crates/servicepoint/src/c_slice.rs +++ b/crates/servicepoint_binding_c/src/c_slice.rs @@ -1,4 +1,3 @@ -#[cfg(feature = "c_api")] #[repr(C)] /// Represents a span of memory (`&mut [u8]` ) as a struct usable by C code. /// diff --git a/crates/servicepoint_binding_c/src/command.rs b/crates/servicepoint_binding_c/src/command.rs new file mode 100644 index 0000000..2d4e7a1 --- /dev/null +++ b/crates/servicepoint_binding_c/src/command.rs @@ -0,0 +1,166 @@ +use std::ptr::null_mut; + +use servicepoint::{ + BitVec, ByteGrid, CompressionCode, Origin, Packet, PixelGrid, +}; +pub use servicepoint::{Brightness, Command, Offset}; + +/// Tries to turn a `Packet` into a `Command`. The packet is gets deallocated in the process. +/// +/// Returns: pointer to command or NULL +#[no_mangle] +pub unsafe extern "C" fn sp_command_try_from_packet( + packet: *mut Packet, +) -> *mut Command { + let packet = *Box::from_raw(packet); + match Command::try_from(packet) { + Err(_) => null_mut(), + Ok(command) => Box::into_raw(Box::new(command)), + } +} + +/// Clones a `Command` instance +#[no_mangle] +pub unsafe extern "C" fn sp_command_clone( + original: *const Command, +) -> *mut Command { + Box::into_raw(Box::new((*original).clone())) +} + +/// Allocates a new `Command::Clear` instance +#[no_mangle] +pub unsafe extern "C" fn sp_command_clear() -> *mut Command { + Box::into_raw(Box::new(Command::Clear)) +} + +/// Allocates a new `Command::HardReset` instance +#[no_mangle] +pub unsafe extern "C" fn sp_command_hard_reset() -> *mut Command { + Box::into_raw(Box::new(Command::HardReset)) +} + +/// Allocates a new `Command::FadeOut` instance +#[no_mangle] +pub unsafe extern "C" fn sp_command_fade_out() -> *mut Command { + Box::into_raw(Box::new(Command::FadeOut)) +} + +/// Allocates a new `Command::Brightness` instance +#[no_mangle] +pub unsafe extern "C" fn sp_command_brightness( + brightness: Brightness, +) -> *mut Command { + Box::into_raw(Box::new(Command::Brightness(brightness))) +} + +/// Allocates a new `Command::CharBrightness` instance. +/// The passed `ByteGrid` gets deallocated in the process. +#[no_mangle] +pub unsafe extern "C" fn sp_command_char_brightness( + x: usize, + y: usize, + byte_grid: *mut ByteGrid, +) -> *mut Command { + let byte_grid = *Box::from_raw(byte_grid); + Box::into_raw(Box::new(Command::CharBrightness(Origin(x, y), byte_grid))) +} + +/// Allocates a new `Command::BitmapLinear` instance. +/// The passed `BitVec` gets deallocated in the process. +#[no_mangle] +pub unsafe extern "C" fn sp_command_bitmap_linear( + offset: Offset, + bit_vec: *mut BitVec, + compression: CompressionCode, +) -> *mut Command { + let bit_vec = *Box::from_raw(bit_vec); + Box::into_raw(Box::new(Command::BitmapLinear( + offset, + bit_vec, + compression, + ))) +} + +/// Allocates a new `Command::BitmapLinearAnd` instance. +/// The passed `BitVec` gets deallocated in the process. +#[no_mangle] +pub unsafe extern "C" fn sp_command_bitmap_linear_and( + offset: Offset, + bit_vec: *mut BitVec, + compression: CompressionCode, +) -> *mut Command { + let bit_vec = *Box::from_raw(bit_vec); + Box::into_raw(Box::new(Command::BitmapLinearAnd( + offset, + bit_vec, + compression, + ))) +} + +/// Allocates a new `Command::BitmapLinearOr` instance. +/// The passed `BitVec` gets deallocated in the process. +#[no_mangle] +pub unsafe extern "C" fn sp_command_bitmap_linear_or( + offset: Offset, + bit_vec: *mut BitVec, + compression: CompressionCode, +) -> *mut Command { + let bit_vec = *Box::from_raw(bit_vec); + Box::into_raw(Box::new(Command::BitmapLinearOr( + offset, + bit_vec, + compression, + ))) +} + +/// Allocates a new `Command::BitmapLinearXor` instance. +/// The passed `BitVec` gets deallocated in the process. +#[no_mangle] +pub unsafe extern "C" fn sp_command_bitmap_linear_xor( + offset: Offset, + bit_vec: *mut BitVec, + compression: CompressionCode, +) -> *mut Command { + let bit_vec = *Box::from_raw(bit_vec); + Box::into_raw(Box::new(Command::BitmapLinearXor( + offset, + bit_vec, + compression, + ))) +} + +/// Allocates a new `Command::Cp437Data` instance. +/// The passed `ByteGrid` gets deallocated in the process. +#[no_mangle] +pub unsafe extern "C" fn sp_command_cp437_data( + x: usize, + y: usize, + byte_grid: *mut ByteGrid, +) -> *mut Command { + let byte_grid = *Box::from_raw(byte_grid); + Box::into_raw(Box::new(Command::Cp437Data(Origin(x, y), byte_grid))) +} + +/// Allocates a new `Command::BitmapLinearWin` instance. +/// The passed `PixelGrid` gets deallocated in the process. +#[no_mangle] +pub unsafe extern "C" fn sp_command_bitmap_linear_win( + x: usize, + y: usize, + byte_grid: *mut PixelGrid, + compression_code: CompressionCode, +) -> *mut Command { + let byte_grid = *Box::from_raw(byte_grid); + Box::into_raw(Box::new(Command::BitmapLinearWin( + Origin(x, y), + byte_grid, + compression_code, + ))) +} + +/// Deallocates a `Command`. Note that connection_send does this implicitly, so you only need +/// to do this if you use the library for parsing commands. +#[no_mangle] +pub unsafe extern "C" fn sp_command_dealloc(ptr: *mut Command) { + _ = Box::from_raw(ptr); +} diff --git a/crates/servicepoint_binding_c/src/connection.rs b/crates/servicepoint_binding_c/src/connection.rs new file mode 100644 index 0000000..b1ea334 --- /dev/null +++ b/crates/servicepoint_binding_c/src/connection.rs @@ -0,0 +1,40 @@ +use std::ffi::{c_char, CStr}; +use std::ptr::null_mut; + +pub use servicepoint::Connection; +use servicepoint::Packet; + +/// Creates a new instance of Connection. +/// The returned instance has to be deallocated with `connection_dealloc`. +/// +/// returns: NULL if connection fails or connected instance +/// +/// Panics: bad string encoding +#[no_mangle] +pub unsafe extern "C" fn sp_connection_open( + host: *const c_char, +) -> *mut Connection { + let host = CStr::from_ptr(host).to_str().expect("Bad encoding"); + let connection = match Connection::open(host) { + Err(_) => return null_mut(), + Ok(value) => value, + }; + + Box::into_raw(Box::new(connection)) +} + +/// Sends the command instance. The instance is consumed / destroyed and cannot be used after this call. +#[no_mangle] +pub unsafe extern "C" fn sp_connection_send( + connection: *const Connection, + command_ptr: *mut Packet, +) -> bool { + let packet = Box::from_raw(command_ptr); + (*connection).send(*packet).is_ok() +} + +/// Closes and deallocates a connection instance +#[no_mangle] +pub unsafe extern "C" fn sp_connection_dealloc(ptr: *mut Connection) { + _ = Box::from_raw(ptr); +} diff --git a/crates/servicepoint_binding_c/src/lib.rs b/crates/servicepoint_binding_c/src/lib.rs index e69de29..4ecbd5d 100644 --- a/crates/servicepoint_binding_c/src/lib.rs +++ b/crates/servicepoint_binding_c/src/lib.rs @@ -0,0 +1,14 @@ +pub use servicepoint::{ + CompressionCode, PIXEL_COUNT, PIXEL_HEIGHT, PIXEL_WIDTH, TILE_HEIGHT, + TILE_SIZE, TILE_WIDTH, +}; + +pub mod bit_vec; +pub mod byte_grid; +pub mod c_slice; +pub mod command; +pub mod connection; +pub mod packet; +pub mod pixel_grid; + +pub const FRAME_PACING_MS: u32 = servicepoint::FRAME_PACING.as_millis() as u32; diff --git a/crates/servicepoint_binding_c/src/packet.rs b/crates/servicepoint_binding_c/src/packet.rs new file mode 100644 index 0000000..9e90f3f --- /dev/null +++ b/crates/servicepoint_binding_c/src/packet.rs @@ -0,0 +1,37 @@ +use std::ptr::null_mut; + +use servicepoint::Command; +pub use servicepoint::Packet; + +/// Turns a `Command` into a `Packet`. The command gets deallocated in the process. +#[no_mangle] +pub unsafe extern "C" fn sp_packet_from_command( + command: *mut Command, +) -> *mut Packet { + let command = *Box::from_raw(command); + let packet = command.into(); + Box::into_raw(Box::new(packet)) +} + +/// Tries to load a `Packet` from the passed array with the specified length. +/// +/// returns: NULL in case of an error, pointer to the allocated packet otherwise +#[no_mangle] +pub unsafe extern "C" fn sp_packet_try_load( + data: *const u8, + length: usize, +) -> *mut Packet { + let data = std::slice::from_raw_parts(data, length); + match Packet::try_from(data) { + Err(_) => null_mut(), + Ok(packet) => Box::into_raw(Box::new(packet)), + } +} + +/// Deallocates a `Packet`. +/// +/// Note: do not call this if the instance has been consumed in another way, e.g. by sending it. +#[no_mangle] +pub unsafe extern "C" fn sp_packet_dealloc(this: *mut Packet) { + _ = Box::from_raw(this) +} diff --git a/crates/servicepoint_binding_c/src/pixel_grid.rs b/crates/servicepoint_binding_c/src/pixel_grid.rs new file mode 100644 index 0000000..87090d9 --- /dev/null +++ b/crates/servicepoint_binding_c/src/pixel_grid.rs @@ -0,0 +1,102 @@ +use servicepoint::{DataRef, Grid, PixelGrid}; + +use crate::c_slice::CByteSlice; + +/// Creates a new `PixelGrid` instance. +/// The returned instance has to be freed with `pixel_grid_dealloc`. +#[no_mangle] +pub unsafe extern "C" fn sp_pixel_grid_new( + width: usize, + height: usize, +) -> *mut PixelGrid { + Box::into_raw(Box::new(PixelGrid::new(width, height))) +} + +/// Loads a `PixelGrid` with the specified dimensions from the provided data. +/// The returned instance has to be freed with `pixel_grid_dealloc`. +#[no_mangle] +pub unsafe extern "C" fn sp_pixel_grid_load( + width: usize, + height: usize, + data: *const u8, + data_length: usize, +) -> *mut PixelGrid { + let data = std::slice::from_raw_parts(data, data_length); + Box::into_raw(Box::new(PixelGrid::load(width, height, data))) +} + +/// Clones a `PixelGrid`. +/// The returned instance has to be freed with `pixel_grid_dealloc`. +#[no_mangle] +pub unsafe extern "C" fn sp_pixel_grid_clone( + this: *const PixelGrid, +) -> *mut PixelGrid { + Box::into_raw(Box::new((*this).clone())) +} + +/// Deallocates a `PixelGrid`. +/// +/// Note: do not call this if the grid has been consumed in another way, e.g. to create a command. +#[no_mangle] +pub unsafe extern "C" fn sp_pixel_grid_dealloc(this: *mut PixelGrid) { + _ = Box::from_raw(this); +} + +/// Get the current value at the specified position +#[no_mangle] +pub unsafe extern "C" fn sp_pixel_grid_get( + this: *const PixelGrid, + x: usize, + y: usize, +) -> bool { + (*this).get(x, y) +} + +/// Sets the current value at the specified position +#[no_mangle] +pub unsafe extern "C" fn sp_pixel_grid_set( + this: *mut PixelGrid, + x: usize, + y: usize, + value: bool, +) { + (*this).set(x, y, value); +} + +/// Fills the whole `PixelGrid` with the specified value +#[no_mangle] +pub unsafe extern "C" fn sp_pixel_grid_fill(this: *mut PixelGrid, value: bool) { + (*this).fill(value); +} + +/// Gets the width in pixels of the `PixelGrid` instance. +#[no_mangle] +pub unsafe extern "C" fn sp_pixel_grid_width(this: *const PixelGrid) -> usize { + (*this).width() +} + +/// Gets the height in pixels of the `PixelGrid` instance. +#[no_mangle] +pub unsafe extern "C" fn sp_pixel_grid_height(this: *const PixelGrid) -> usize { + (*this).height() +} + +/// Gets an unsafe reference to the data of the `PixelGrid` instance. +/// +/// ## Safety +/// +/// The caller has to make sure to never access the returned memory after the `PixelGrid` +/// instance has been consumed or manually deallocated. +/// +/// Reading and writing concurrently to either the original instance or the returned data will +/// result in undefined behavior. +#[no_mangle] +pub unsafe extern "C" fn sp_pixel_grid_unsafe_data_ref( + this: *mut PixelGrid, +) -> CByteSlice { + let data = (*this).data_ref_mut(); + CByteSlice { + start: data.as_mut_ptr_range().start, + length: data.len(), + } +} diff --git a/crates/servicepoint_binding_cs/Cargo.toml b/crates/servicepoint_binding_cs/Cargo.toml index ed651f5..cfc909c 100644 --- a/crates/servicepoint_binding_cs/Cargo.toml +++ b/crates/servicepoint_binding_cs/Cargo.toml @@ -8,8 +8,8 @@ readme = "../../README.md" [lib] crate-type = ["cdylib"] -[dependencies] -servicepoint = { path = "../servicepoint", features = ["c_api"] } - [build-dependencies] csbindgen = "1.8.0" + +[dependencies] +servicepoint_binding_c = { path = "../servicepoint_binding_c" } diff --git a/crates/servicepoint_binding_cs/ServicePoint.sln b/crates/servicepoint_binding_cs/ServicePoint.sln index c505f07..29b9889 100644 --- a/crates/servicepoint_binding_cs/ServicePoint.sln +++ b/crates/servicepoint_binding_cs/ServicePoint.sln @@ -1,8 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServicePoint", "src/ServicePoint.csproj", "{70EFFA3F-012A-4518-9627-466BEAE4252E}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServicePoint", "ServicePoint/ServicePoint.csproj", "{70EFFA3F-012A-4518-9627-466BEAE4252E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "lang-cs", "../examples/lang_cs/lang_cs.csproj", "{DA3B8B6E-993A-47DA-844B-F92AF520FF59}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "lang-cs", "../../examples/lang_cs/lang_cs.csproj", "{DA3B8B6E-993A-47DA-844B-F92AF520FF59}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/crates/servicepoint_binding_cs/src/BindGen/ServicePoint.g.cs b/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs similarity index 52% rename from crates/servicepoint_binding_cs/src/BindGen/ServicePoint.g.cs rename to crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs index d138126..fd8f466 100644 --- a/crates/servicepoint_binding_cs/src/BindGen/ServicePoint.g.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs @@ -12,218 +12,228 @@ namespace ServicePoint.BindGen { public static unsafe partial class NativeMethods { - const string __DllName = "servicepoint"; + const string __DllName = "servicepoint_binding_c"; + public const nuint TILE_SIZE = 8; + public const nuint TILE_WIDTH = 56; + public const nuint TILE_HEIGHT = 20; /// Creates a new `BitVec` instance. The returned instance has to be freed with `bit_vec_dealloc`. - [DllImport(__DllName, EntryPoint = "sp2_bit_vec_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BitVec* sp2_bit_vec_new(nuint size); + [DllImport(__DllName, EntryPoint = "sp_bit_vec_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern BitVec* sp_bit_vec_new(nuint size); /// Loads a `BitVec` from the provided data. The returned instance has to be freed with `bit_vec_dealloc`. - [DllImport(__DllName, EntryPoint = "sp2_bit_vec_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BitVec* sp2_bit_vec_load(byte* data, nuint data_length); + [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); /// Clones a `BitVec`. The returned instance has to be freed with `bit_vec_dealloc`. - [DllImport(__DllName, EntryPoint = "sp2_bit_vec_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BitVec* sp2_bit_vec_clone(BitVec* @this); + [DllImport(__DllName, EntryPoint = "sp_bit_vec_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern BitVec* sp_bit_vec_clone(BitVec* @this); /// Deallocates a `BitVec`. Note: do not call this if the grid has been consumed in another way, e.g. to create a command. - [DllImport(__DllName, EntryPoint = "sp2_bit_vec_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp2_bit_vec_dealloc(BitVec* @this); + [DllImport(__DllName, EntryPoint = "sp_bit_vec_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bit_vec_dealloc(BitVec* @this); /// Gets the value of a bit from the `BitVec`. - [DllImport(__DllName, EntryPoint = "sp2_bit_vec_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + [DllImport(__DllName, EntryPoint = "sp_bit_vec_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp2_bit_vec_get(BitVec* @this, nuint index); + public static extern bool sp_bit_vec_get(BitVec* @this, nuint index); /// Sets the value of a bit in the `BitVec`. - [DllImport(__DllName, EntryPoint = "sp2_bit_vec_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + [DllImport(__DllName, EntryPoint = "sp_bit_vec_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp2_bit_vec_set(BitVec* @this, nuint index, [MarshalAs(UnmanagedType.U1)] bool value); + public static extern bool sp_bit_vec_set(BitVec* @this, nuint index, [MarshalAs(UnmanagedType.U1)] bool value); /// Sets the value of all bits in the `BitVec`. - [DllImport(__DllName, EntryPoint = "sp2_bit_vec_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp2_bit_vec_fill(BitVec* @this, [MarshalAs(UnmanagedType.U1)] bool value); + [DllImport(__DllName, EntryPoint = "sp_bit_vec_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_bit_vec_fill(BitVec* @this, [MarshalAs(UnmanagedType.U1)] bool value); /// Gets the length of the `BitVec` in bits. - [DllImport(__DllName, EntryPoint = "sp2_bit_vec_len", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp2_bit_vec_len(BitVec* @this); + [DllImport(__DllName, EntryPoint = "sp_bit_vec_len", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern nuint sp_bit_vec_len(BitVec* @this); /// Returns true if length is 0. - [DllImport(__DllName, EntryPoint = "sp2_bit_vec_is_empty", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + [DllImport(__DllName, EntryPoint = "sp_bit_vec_is_empty", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp2_bit_vec_is_empty(BitVec* @this); + public static extern bool sp_bit_vec_is_empty(BitVec* @this); /// Gets an unsafe reference to the data of the `BitVec` instance. ## Safety The caller has to make sure to never access the returned memory after the `BitVec` instance has been consumed or manually deallocated. Reading and writing concurrently to either the original instance or the returned data will result in undefined behavior. - [DllImport(__DllName, EntryPoint = "sp2_bit_vec_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern CByteSlice sp2_bit_vec_unsafe_data_ref(BitVec* @this); + [DllImport(__DllName, EntryPoint = "sp_bit_vec_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern CByteSlice sp_bit_vec_unsafe_data_ref(BitVec* @this); /// Creates a new `ByteGrid` instance. The returned instance has to be freed with `byte_grid_dealloc`. - [DllImport(__DllName, EntryPoint = "sp2_byte_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteGrid* sp2_byte_grid_new(nuint width, nuint height); + [DllImport(__DllName, EntryPoint = "sp_byte_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern ByteGrid* sp_byte_grid_new(nuint width, nuint height); /// Loads a `ByteGrid` with the specified dimensions from the provided data. The returned instance has to be freed with `byte_grid_dealloc`. - [DllImport(__DllName, EntryPoint = "sp2_byte_grid_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteGrid* sp2_byte_grid_load(nuint width, nuint height, byte* data, nuint data_length); + [DllImport(__DllName, EntryPoint = "sp_byte_grid_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern ByteGrid* sp_byte_grid_load(nuint width, nuint height, byte* data, nuint data_length); /// Clones a `ByteGrid`. The returned instance has to be freed with `byte_grid_dealloc`. - [DllImport(__DllName, EntryPoint = "sp2_byte_grid_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteGrid* sp2_byte_grid_clone(ByteGrid* @this); + [DllImport(__DllName, EntryPoint = "sp_byte_grid_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern ByteGrid* sp_byte_grid_clone(ByteGrid* @this); /// Deallocates a `ByteGrid`. Note: do not call this if the grid has been consumed in another way, e.g. to create a command. - [DllImport(__DllName, EntryPoint = "sp2_byte_grid_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp2_byte_grid_dealloc(ByteGrid* @this); + [DllImport(__DllName, EntryPoint = "sp_byte_grid_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_byte_grid_dealloc(ByteGrid* @this); /// Get the current value at the specified position - [DllImport(__DllName, EntryPoint = "sp2_byte_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern byte sp2_byte_grid_get(ByteGrid* @this, nuint x, nuint y); + [DllImport(__DllName, EntryPoint = "sp_byte_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern byte sp_byte_grid_get(ByteGrid* @this, nuint x, nuint y); /// Sets the current value at the specified position - [DllImport(__DllName, EntryPoint = "sp2_byte_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp2_byte_grid_set(ByteGrid* @this, nuint x, nuint y, byte value); + [DllImport(__DllName, EntryPoint = "sp_byte_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_byte_grid_set(ByteGrid* @this, nuint x, nuint y, byte value); /// Fills the whole `ByteGrid` with the specified value - [DllImport(__DllName, EntryPoint = "sp2_byte_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp2_byte_grid_fill(ByteGrid* @this, byte value); + [DllImport(__DllName, EntryPoint = "sp_byte_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_byte_grid_fill(ByteGrid* @this, byte value); /// Gets the width in pixels of the `ByteGrid` instance. - [DllImport(__DllName, EntryPoint = "sp2_byte_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp2_byte_grid_width(ByteGrid* @this); + [DllImport(__DllName, EntryPoint = "sp_byte_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern nuint sp_byte_grid_width(ByteGrid* @this); /// Gets the height in pixels of the `ByteGrid` instance. - [DllImport(__DllName, EntryPoint = "sp2_byte_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp2_byte_grid_height(ByteGrid* @this); + [DllImport(__DllName, EntryPoint = "sp_byte_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern nuint sp_byte_grid_height(ByteGrid* @this); /// Gets an unsafe reference to the data of the `ByteGrid` instance. ## Safety The caller has to make sure to never access the returned memory after the `ByteGrid` instance has been consumed or manually deallocated. Reading and writing concurrently to either the original instance or the returned data will result in undefined behavior. - [DllImport(__DllName, EntryPoint = "sp2_byte_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern CByteSlice sp2_byte_grid_unsafe_data_ref(ByteGrid* @this); + [DllImport(__DllName, EntryPoint = "sp_byte_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern CByteSlice sp_byte_grid_unsafe_data_ref(ByteGrid* @this); /// Tries to turn a `Packet` into a `Command`. The packet is gets deallocated in the process. Returns: pointer to command or NULL - [DllImport(__DllName, EntryPoint = "sp2_command_try_from_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp2_command_try_from_packet(Packet* packet); + [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 `Command` instance - [DllImport(__DllName, EntryPoint = "sp2_command_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp2_command_clone(Command* original); + [DllImport(__DllName, EntryPoint = "sp_command_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_clone(Command* original); /// Allocates a new `Command::Clear` instance - [DllImport(__DllName, EntryPoint = "sp2_command_clear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp2_command_clear(); + [DllImport(__DllName, EntryPoint = "sp_command_clear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_clear(); /// Allocates a new `Command::HardReset` instance - [DllImport(__DllName, EntryPoint = "sp2_command_hard_reset", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp2_command_hard_reset(); + [DllImport(__DllName, EntryPoint = "sp_command_hard_reset", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_hard_reset(); /// Allocates a new `Command::FadeOut` instance - [DllImport(__DllName, EntryPoint = "sp2_command_fade_out", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp2_command_fade_out(); + [DllImport(__DllName, EntryPoint = "sp_command_fade_out", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_fade_out(); /// Allocates a new `Command::Brightness` instance - [DllImport(__DllName, EntryPoint = "sp2_command_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp2_command_brightness(byte brightness); + [DllImport(__DllName, EntryPoint = "sp_command_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_brightness(byte brightness); /// Allocates a new `Command::CharBrightness` instance. The passed `ByteGrid` gets deallocated in the process. - [DllImport(__DllName, EntryPoint = "sp2_command_char_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp2_command_char_brightness(nuint x, nuint y, ByteGrid* byte_grid); + [DllImport(__DllName, EntryPoint = "sp_command_char_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_char_brightness(nuint x, nuint y, ByteGrid* byte_grid); /// Allocates a new `Command::BitmapLinear` instance. The passed `BitVec` gets deallocated in the process. - [DllImport(__DllName, EntryPoint = "sp2_command_bitmap_linear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp2_command_bitmap_linear(nuint offset, BitVec* bit_vec, CompressionCode compression); + [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); /// Allocates a new `Command::BitmapLinearAnd` instance. The passed `BitVec` gets deallocated in the process. - [DllImport(__DllName, EntryPoint = "sp2_command_bitmap_linear_and", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp2_command_bitmap_linear_and(nuint offset, BitVec* bit_vec, CompressionCode compression); + [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); /// Allocates a new `Command::BitmapLinearOr` instance. The passed `BitVec` gets deallocated in the process. - [DllImport(__DllName, EntryPoint = "sp2_command_bitmap_linear_or", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp2_command_bitmap_linear_or(nuint offset, BitVec* bit_vec, CompressionCode compression); + [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); /// Allocates a new `Command::BitmapLinearXor` instance. The passed `BitVec` gets deallocated in the process. - [DllImport(__DllName, EntryPoint = "sp2_command_bitmap_linear_xor", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp2_command_bitmap_linear_xor(nuint offset, BitVec* bit_vec, CompressionCode compression); + [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); /// Allocates a new `Command::Cp437Data` instance. The passed `ByteGrid` gets deallocated in the process. - [DllImport(__DllName, EntryPoint = "sp2_command_cp437_data", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp2_command_cp437_data(nuint x, nuint y, ByteGrid* byte_grid); + [DllImport(__DllName, EntryPoint = "sp_command_cp437_data", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Command* sp_command_cp437_data(nuint x, nuint y, ByteGrid* byte_grid); /// Allocates a new `Command::BitmapLinearWin` instance. The passed `PixelGrid` gets deallocated in the process. - [DllImport(__DllName, EntryPoint = "sp2_command_bitmap_linear_win", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp2_command_bitmap_linear_win(nuint x, nuint y, PixelGrid* byte_grid, CompressionCode compression_code); + [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* byte_grid, CompressionCode compression_code); /// Deallocates a `Command`. Note that connection_send does this implicitly, so you only need to do this if you use the library for parsing commands. - [DllImport(__DllName, EntryPoint = "sp2_command_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp2_command_dealloc(Command* ptr); + [DllImport(__DllName, EntryPoint = "sp_command_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_command_dealloc(Command* ptr); /// Creates a new instance of Connection. The returned instance has to be deallocated with `connection_dealloc`. returns: NULL if connection fails or connected instance Panics: bad string encoding - [DllImport(__DllName, EntryPoint = "sp2_connection_open", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Connection* sp2_connection_open(byte* host); + [DllImport(__DllName, EntryPoint = "sp_connection_open", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Connection* sp_connection_open(byte* host); /// Sends the command instance. The instance is consumed / destroyed and cannot be used after this call. - [DllImport(__DllName, EntryPoint = "sp2_connection_send", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + [DllImport(__DllName, EntryPoint = "sp_connection_send", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp2_connection_send(Connection* connection, Packet* command_ptr); + public static extern bool sp_connection_send(Connection* connection, Packet* command_ptr); /// Closes and deallocates a connection instance - [DllImport(__DllName, EntryPoint = "sp2_connection_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp2_connection_dealloc(Connection* ptr); + [DllImport(__DllName, EntryPoint = "sp_connection_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_connection_dealloc(Connection* ptr); /// Creates a new `PixelGrid` instance. The returned instance has to be freed with `pixel_grid_dealloc`. - [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern PixelGrid* sp2_pixel_grid_new(nuint width, nuint height); + [DllImport(__DllName, EntryPoint = "sp_pixel_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern PixelGrid* sp_pixel_grid_new(nuint width, nuint height); /// Loads a `PixelGrid` with the specified dimensions from the provided data. The returned instance has to be freed with `pixel_grid_dealloc`. - [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern PixelGrid* sp2_pixel_grid_load(nuint width, nuint height, byte* data, nuint data_length); + [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); /// Clones a `PixelGrid`. The returned instance has to be freed with `pixel_grid_dealloc`. - [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern PixelGrid* sp2_pixel_grid_clone(PixelGrid* @this); + [DllImport(__DllName, EntryPoint = "sp_pixel_grid_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern PixelGrid* sp_pixel_grid_clone(PixelGrid* @this); /// Deallocates a `PixelGrid`. Note: do not call this if the grid has been consumed in another way, e.g. to create a command. - [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp2_pixel_grid_dealloc(PixelGrid* @this); + [DllImport(__DllName, EntryPoint = "sp_pixel_grid_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_pixel_grid_dealloc(PixelGrid* @this); /// Get the current value at the specified position - [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + [DllImport(__DllName, EntryPoint = "sp_pixel_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp2_pixel_grid_get(PixelGrid* @this, nuint x, nuint y); + public static extern bool sp_pixel_grid_get(PixelGrid* @this, nuint x, nuint y); /// Sets the current value at the specified position - [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp2_pixel_grid_set(PixelGrid* @this, nuint x, nuint y, [MarshalAs(UnmanagedType.U1)] bool value); + [DllImport(__DllName, EntryPoint = "sp_pixel_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_pixel_grid_set(PixelGrid* @this, nuint x, nuint y, [MarshalAs(UnmanagedType.U1)] bool value); /// Fills the whole `PixelGrid` with the specified value - [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp2_pixel_grid_fill(PixelGrid* @this, [MarshalAs(UnmanagedType.U1)] bool value); + [DllImport(__DllName, EntryPoint = "sp_pixel_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_pixel_grid_fill(PixelGrid* @this, [MarshalAs(UnmanagedType.U1)] bool value); /// Gets the width in pixels of the `PixelGrid` instance. - [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp2_pixel_grid_width(PixelGrid* @this); + [DllImport(__DllName, EntryPoint = "sp_pixel_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern nuint sp_pixel_grid_width(PixelGrid* @this); /// Gets the height in pixels of the `PixelGrid` instance. - [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp2_pixel_grid_height(PixelGrid* @this); + [DllImport(__DllName, EntryPoint = "sp_pixel_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern nuint sp_pixel_grid_height(PixelGrid* @this); /// Gets an unsafe reference to the data of the `PixelGrid` instance. ## Safety The caller has to make sure to never access the returned memory after the `PixelGrid` instance has been consumed or manually deallocated. Reading and writing concurrently to either the original instance or the returned data will result in undefined behavior. - [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern CByteSlice sp2_pixel_grid_unsafe_data_ref(PixelGrid* @this); + [DllImport(__DllName, EntryPoint = "sp_pixel_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern CByteSlice sp_pixel_grid_unsafe_data_ref(PixelGrid* @this); /// Turns a `Command` into a `Packet`. The command gets deallocated in the process. - [DllImport(__DllName, EntryPoint = "sp2_packet_from_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Packet* sp2_packet_from_command(Command* command); + [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 `Packet` from the passed array with the specified length. returns: NULL in case of an error, pointer to the allocated packet otherwise - [DllImport(__DllName, EntryPoint = "sp2_packet_try_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Packet* sp2_packet_try_load(byte* data, nuint length); + [DllImport(__DllName, EntryPoint = "sp_packet_try_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern Packet* sp_packet_try_load(byte* data, nuint length); /// Deallocates a `Packet`. Note: do not call this if the instance has been consumed in another way, e.g. by sending it. - [DllImport(__DllName, EntryPoint = "sp2_packet_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp2_packet_dealloc(Packet* @this); + [DllImport(__DllName, EntryPoint = "sp_packet_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void sp_packet_dealloc(Packet* @this); } + [StructLayout(LayoutKind.Sequential)] + public unsafe partial struct CByteSlice + { + public byte* start; + public nuint length; + } + [StructLayout(LayoutKind.Sequential)] public unsafe partial struct BitVec { @@ -244,13 +254,6 @@ namespace ServicePoint.BindGen { } - [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct CByteSlice - { - public byte* start; - public nuint length; - } - [StructLayout(LayoutKind.Sequential)] public unsafe partial struct Packet { diff --git a/crates/servicepoint_binding_cs/src/BitVec.cs b/crates/servicepoint_binding_cs/ServicePoint/BitVec.cs similarity index 63% rename from crates/servicepoint_binding_cs/src/BitVec.cs rename to crates/servicepoint_binding_cs/ServicePoint/BitVec.cs index 3d61d92..13b2200 100644 --- a/crates/servicepoint_binding_cs/src/BitVec.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/BitVec.cs @@ -8,7 +8,7 @@ public sealed class BitVec : SpNativeInstance { unsafe { - return new BitVec(NativeMethods.sp2_bit_vec_new((nuint)size)); + return new BitVec(NativeMethods.sp_bit_vec_new((nuint)size)); } } @@ -18,7 +18,7 @@ public sealed class BitVec : SpNativeInstance { fixed (byte* bytesPtr = bytes) { - return new BitVec(NativeMethods.sp2_bit_vec_load(bytesPtr, (nuint)bytes.Length)); + return new BitVec(NativeMethods.sp_bit_vec_load(bytesPtr, (nuint)bytes.Length)); } } } @@ -27,7 +27,7 @@ public sealed class BitVec : SpNativeInstance { unsafe { - return new BitVec(NativeMethods.sp2_bit_vec_clone(Instance)); + return new BitVec(NativeMethods.sp_bit_vec_clone(Instance)); } } @@ -37,14 +37,14 @@ public sealed class BitVec : SpNativeInstance { unsafe { - return NativeMethods.sp2_bit_vec_get(Instance, (nuint)index); + return NativeMethods.sp_bit_vec_get(Instance, (nuint)index); } } set { unsafe { - NativeMethods.sp2_bit_vec_set(Instance, (nuint)index, value); + NativeMethods.sp_bit_vec_set(Instance, (nuint)index, value); } } } @@ -53,7 +53,7 @@ public sealed class BitVec : SpNativeInstance { unsafe { - NativeMethods.sp2_bit_vec_fill(Instance, value); + NativeMethods.sp_bit_vec_fill(Instance, value); } } @@ -63,7 +63,7 @@ public sealed class BitVec : SpNativeInstance { unsafe { - return (int)NativeMethods.sp2_bit_vec_len(Instance); + return (int)NativeMethods.sp_bit_vec_len(Instance); } } } @@ -74,7 +74,7 @@ public sealed class BitVec : SpNativeInstance { unsafe { - var slice = NativeMethods.sp2_bit_vec_unsafe_data_ref(Instance); + var slice = NativeMethods.sp_bit_vec_unsafe_data_ref(Instance); return new Span(slice.start, (int)slice.length); } } @@ -86,6 +86,6 @@ public sealed class BitVec : SpNativeInstance private protected override unsafe void Dealloc() { - NativeMethods.sp2_bit_vec_dealloc(Instance); + NativeMethods.sp_bit_vec_dealloc(Instance); } } diff --git a/crates/servicepoint_binding_cs/src/ByteGrid.cs b/crates/servicepoint_binding_cs/ServicePoint/ByteGrid.cs similarity index 72% rename from crates/servicepoint_binding_cs/src/ByteGrid.cs rename to crates/servicepoint_binding_cs/ServicePoint/ByteGrid.cs index 2722a68..e6c4fdc 100644 --- a/crates/servicepoint_binding_cs/src/ByteGrid.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/ByteGrid.cs @@ -9,7 +9,7 @@ public sealed class ByteGrid : SpNativeInstance { unsafe { - return new ByteGrid(NativeMethods.sp2_byte_grid_new((nuint)width, (nuint)height)); + return new ByteGrid(NativeMethods.sp_byte_grid_new((nuint)width, (nuint)height)); } } @@ -19,7 +19,7 @@ public sealed class ByteGrid : SpNativeInstance { fixed (byte* bytesPtr = bytes) { - return new ByteGrid(NativeMethods.sp2_byte_grid_load((nuint)width, (nuint)height, bytesPtr, + return new ByteGrid(NativeMethods.sp_byte_grid_load((nuint)width, (nuint)height, bytesPtr, (nuint)bytes.Length)); } } @@ -29,7 +29,7 @@ public sealed class ByteGrid : SpNativeInstance { unsafe { - return new ByteGrid(NativeMethods.sp2_byte_grid_clone(Instance)); + return new ByteGrid(NativeMethods.sp_byte_grid_clone(Instance)); } } @@ -39,14 +39,14 @@ public sealed class ByteGrid : SpNativeInstance { unsafe { - return NativeMethods.sp2_byte_grid_get(Instance, (nuint)x, (nuint)y); + return NativeMethods.sp_byte_grid_get(Instance, (nuint)x, (nuint)y); } } set { unsafe { - NativeMethods.sp2_byte_grid_set(Instance, (nuint)x, (nuint)y, value); + NativeMethods.sp_byte_grid_set(Instance, (nuint)x, (nuint)y, value); } } } @@ -85,7 +85,7 @@ public sealed class ByteGrid : SpNativeInstance { unsafe { - NativeMethods.sp2_byte_grid_fill(Instance, value); + NativeMethods.sp_byte_grid_fill(Instance, value); } } @@ -95,7 +95,7 @@ public sealed class ByteGrid : SpNativeInstance { unsafe { - return (int)NativeMethods.sp2_byte_grid_width(Instance); + return (int)NativeMethods.sp_byte_grid_width(Instance); } } } @@ -106,7 +106,7 @@ public sealed class ByteGrid : SpNativeInstance { unsafe { - return (int)NativeMethods.sp2_byte_grid_height(Instance); + return (int)NativeMethods.sp_byte_grid_height(Instance); } } } @@ -117,7 +117,7 @@ public sealed class ByteGrid : SpNativeInstance { unsafe { - var slice = NativeMethods.sp2_byte_grid_unsafe_data_ref(Instance); + var slice = NativeMethods.sp_byte_grid_unsafe_data_ref(Instance); return new Span(slice.start, (int)slice.length); } } @@ -129,6 +129,6 @@ public sealed class ByteGrid : SpNativeInstance private protected override unsafe void Dealloc() { - NativeMethods.sp2_byte_grid_dealloc(Instance); + NativeMethods.sp_byte_grid_dealloc(Instance); } } diff --git a/crates/servicepoint_binding_cs/src/Command.cs b/crates/servicepoint_binding_cs/ServicePoint/Command.cs similarity index 64% rename from crates/servicepoint_binding_cs/src/Command.cs rename to crates/servicepoint_binding_cs/ServicePoint/Command.cs index b25b564..b9d0d3c 100644 --- a/crates/servicepoint_binding_cs/src/Command.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/Command.cs @@ -9,7 +9,7 @@ public sealed class Command : SpNativeInstance { unsafe { - var result = NativeMethods.sp2_command_try_from_packet(packet.Into()); + var result = NativeMethods.sp_command_try_from_packet(packet.Into()); if (result == null) { command = null; @@ -25,7 +25,7 @@ public sealed class Command : SpNativeInstance { unsafe { - return new Command(NativeMethods.sp2_command_clone(Instance)); + return new Command(NativeMethods.sp_command_clone(Instance)); } } @@ -33,7 +33,7 @@ public sealed class Command : SpNativeInstance { unsafe { - return new Command(NativeMethods.sp2_command_clear()); + return new Command(NativeMethods.sp_command_clear()); } } @@ -41,7 +41,7 @@ public sealed class Command : SpNativeInstance { unsafe { - return new Command(NativeMethods.sp2_command_hard_reset()); + return new Command(NativeMethods.sp_command_hard_reset()); } } @@ -49,7 +49,7 @@ public sealed class Command : SpNativeInstance { unsafe { - return new Command(NativeMethods.sp2_command_fade_out()); + return new Command(NativeMethods.sp_command_fade_out()); } } @@ -57,7 +57,7 @@ public sealed class Command : SpNativeInstance { unsafe { - return new Command(NativeMethods.sp2_command_brightness(brightness)); + return new Command(NativeMethods.sp_command_brightness(brightness)); } } @@ -65,7 +65,7 @@ public sealed class Command : SpNativeInstance { unsafe { - return new Command(NativeMethods.sp2_command_char_brightness((ushort)x, (ushort)y, grid.Into())); + return new Command(NativeMethods.sp_command_char_brightness((ushort)x, (ushort)y, grid.Into())); } } @@ -74,7 +74,7 @@ public sealed class Command : SpNativeInstance unsafe { return new Command( - NativeMethods.sp2_command_bitmap_linear((ushort)offset, bitVec.Into(), compressionCode)); + NativeMethods.sp_command_bitmap_linear((ushort)offset, bitVec.Into(), compressionCode)); } } @@ -83,7 +83,7 @@ public sealed class Command : SpNativeInstance unsafe { return new Command( - NativeMethods.sp2_command_bitmap_linear_and((ushort)offset, bitVec.Into(), compressionCode)); + NativeMethods.sp_command_bitmap_linear_and((ushort)offset, bitVec.Into(), compressionCode)); } } @@ -92,7 +92,7 @@ public sealed class Command : SpNativeInstance unsafe { return new Command( - NativeMethods.sp2_command_bitmap_linear_or((ushort)offset, bitVec.Into(), compressionCode)); + NativeMethods.sp_command_bitmap_linear_or((ushort)offset, bitVec.Into(), compressionCode)); } } @@ -101,7 +101,7 @@ public sealed class Command : SpNativeInstance unsafe { return new Command( - NativeMethods.sp2_command_bitmap_linear_xor((ushort)offset, bitVec.Into(), compressionCode)); + NativeMethods.sp_command_bitmap_linear_xor((ushort)offset, bitVec.Into(), compressionCode)); } } @@ -109,7 +109,7 @@ public sealed class Command : SpNativeInstance { unsafe { - return new Command(NativeMethods.sp2_command_bitmap_linear_win((ushort)x, (ushort)y, pixelGrid.Into(), compression)); + return new Command(NativeMethods.sp_command_bitmap_linear_win((ushort)x, (ushort)y, pixelGrid.Into(), compression)); } } @@ -117,7 +117,7 @@ public sealed class Command : SpNativeInstance { unsafe { - return new Command(NativeMethods.sp2_command_cp437_data((ushort)x, (ushort)y, byteGrid.Into())); + return new Command(NativeMethods.sp_command_cp437_data((ushort)x, (ushort)y, byteGrid.Into())); } } @@ -127,6 +127,6 @@ public sealed class Command : SpNativeInstance private protected override unsafe void Dealloc() { - NativeMethods.sp2_command_dealloc(Instance); + NativeMethods.sp_command_dealloc(Instance); } } diff --git a/crates/servicepoint_binding_cs/src/Connection.cs b/crates/servicepoint_binding_cs/ServicePoint/Connection.cs similarity index 72% rename from crates/servicepoint_binding_cs/src/Connection.cs rename to crates/servicepoint_binding_cs/ServicePoint/Connection.cs index 0f95709..3d1a480 100644 --- a/crates/servicepoint_binding_cs/src/Connection.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/Connection.cs @@ -11,7 +11,7 @@ public sealed class Connection : SpNativeInstance { fixed (byte* bytePtr = Encoding.UTF8.GetBytes(host)) { - return new Connection(NativeMethods.sp2_connection_open(bytePtr)); + return new Connection(NativeMethods.sp_connection_open(bytePtr)); } } } @@ -20,13 +20,13 @@ public sealed class Connection : SpNativeInstance { unsafe { - return NativeMethods.sp2_connection_send(Instance, packet.Into()); + return NativeMethods.sp_connection_send(Instance, packet.Into()); } } private protected override unsafe void Dealloc() { - NativeMethods.sp2_connection_dealloc(Instance); + NativeMethods.sp_connection_dealloc(Instance); } private unsafe Connection(BindGen.Connection* instance) : base(instance) diff --git a/crates/servicepoint_binding_cs/src/Constants.cs b/crates/servicepoint_binding_cs/ServicePoint/Constants.cs similarity index 100% rename from crates/servicepoint_binding_cs/src/Constants.cs rename to crates/servicepoint_binding_cs/ServicePoint/Constants.cs diff --git a/crates/servicepoint_binding_cs/src/GlobalUsings.cs b/crates/servicepoint_binding_cs/ServicePoint/GlobalUsings.cs similarity index 100% rename from crates/servicepoint_binding_cs/src/GlobalUsings.cs rename to crates/servicepoint_binding_cs/ServicePoint/GlobalUsings.cs diff --git a/crates/servicepoint_binding_cs/src/Packet.cs b/crates/servicepoint_binding_cs/ServicePoint/Packet.cs similarity index 76% rename from crates/servicepoint_binding_cs/src/Packet.cs rename to crates/servicepoint_binding_cs/ServicePoint/Packet.cs index 822e601..ab4b08a 100644 --- a/crates/servicepoint_binding_cs/src/Packet.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/Packet.cs @@ -9,7 +9,7 @@ public sealed class Packet : SpNativeInstance { unsafe { - return new Packet(NativeMethods.sp2_packet_from_command(command.Into())); + return new Packet(NativeMethods.sp_packet_from_command(command.Into())); } } @@ -19,7 +19,7 @@ public sealed class Packet : SpNativeInstance { fixed (byte* bytesPtr = bytes) { - var instance = NativeMethods.sp2_packet_try_load(bytesPtr, (nuint)bytes.Length); + var instance = NativeMethods.sp_packet_try_load(bytesPtr, (nuint)bytes.Length); packet = instance == null ? null : new Packet(instance); @@ -34,6 +34,6 @@ public sealed class Packet : SpNativeInstance private protected override unsafe void Dealloc() { - NativeMethods.sp2_packet_dealloc(Instance); + NativeMethods.sp_packet_dealloc(Instance); } } diff --git a/crates/servicepoint_binding_cs/src/PixelGrid.cs b/crates/servicepoint_binding_cs/ServicePoint/PixelGrid.cs similarity index 63% rename from crates/servicepoint_binding_cs/src/PixelGrid.cs rename to crates/servicepoint_binding_cs/ServicePoint/PixelGrid.cs index 2d12f93..1e6fb11 100644 --- a/crates/servicepoint_binding_cs/src/PixelGrid.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/PixelGrid.cs @@ -8,7 +8,7 @@ public sealed class PixelGrid : SpNativeInstance { unsafe { - return new PixelGrid(NativeMethods.sp2_pixel_grid_new((nuint)width, (nuint)height)); + return new PixelGrid(NativeMethods.sp_pixel_grid_new((nuint)width, (nuint)height)); } } @@ -18,7 +18,7 @@ public sealed class PixelGrid : SpNativeInstance { fixed (byte* bytesPtr = bytes) { - return new PixelGrid(NativeMethods.sp2_pixel_grid_load((nuint)width, (nuint)height, bytesPtr, + return new PixelGrid(NativeMethods.sp_pixel_grid_load((nuint)width, (nuint)height, bytesPtr, (nuint)bytes.Length)); } } @@ -28,7 +28,7 @@ public sealed class PixelGrid : SpNativeInstance { unsafe { - return new PixelGrid(NativeMethods.sp2_pixel_grid_clone(Instance)); + return new PixelGrid(NativeMethods.sp_pixel_grid_clone(Instance)); } } @@ -38,14 +38,14 @@ public sealed class PixelGrid : SpNativeInstance { unsafe { - return NativeMethods.sp2_pixel_grid_get(Instance, (nuint)x, (nuint)y); + return NativeMethods.sp_pixel_grid_get(Instance, (nuint)x, (nuint)y); } } set { unsafe { - NativeMethods.sp2_pixel_grid_set(Instance, (nuint)x, (nuint)y, value); + NativeMethods.sp_pixel_grid_set(Instance, (nuint)x, (nuint)y, value); } } } @@ -54,7 +54,7 @@ public sealed class PixelGrid : SpNativeInstance { unsafe { - NativeMethods.sp2_pixel_grid_fill(Instance, value); + NativeMethods.sp_pixel_grid_fill(Instance, value); } } @@ -64,7 +64,7 @@ public sealed class PixelGrid : SpNativeInstance { unsafe { - return (int)NativeMethods.sp2_pixel_grid_width(Instance); + return (int)NativeMethods.sp_pixel_grid_width(Instance); } } } @@ -75,7 +75,7 @@ public sealed class PixelGrid : SpNativeInstance { unsafe { - return (int)NativeMethods.sp2_pixel_grid_height(Instance); + return (int)NativeMethods.sp_pixel_grid_height(Instance); } } } @@ -86,7 +86,7 @@ public sealed class PixelGrid : SpNativeInstance { unsafe { - var slice = NativeMethods.sp2_pixel_grid_unsafe_data_ref(Instance); + var slice = NativeMethods.sp_pixel_grid_unsafe_data_ref(Instance); return new Span(slice.start, (int)slice.length); } } @@ -98,6 +98,6 @@ public sealed class PixelGrid : SpNativeInstance private protected override unsafe void Dealloc() { - NativeMethods.sp2_pixel_grid_dealloc(Instance); + NativeMethods.sp_pixel_grid_dealloc(Instance); } } diff --git a/crates/servicepoint_binding_cs/src/ServicePoint.csproj b/crates/servicepoint_binding_cs/ServicePoint/ServicePoint.csproj similarity index 74% rename from crates/servicepoint_binding_cs/src/ServicePoint.csproj rename to crates/servicepoint_binding_cs/ServicePoint/ServicePoint.csproj index f090283..e82c589 100644 --- a/crates/servicepoint_binding_cs/src/ServicePoint.csproj +++ b/crates/servicepoint_binding_cs/ServicePoint/ServicePoint.csproj @@ -26,45 +26,39 @@ true - - - - - - - - + - + + + + + + + + + - - libservicepoint.so + + libservicepoint_binding_c.so - - - libservicepoint.so + + libservicepoint_binding_c.so - + - - - build.rs - - - diff --git a/crates/servicepoint_binding_cs/src/ServicePointExtensions.cs b/crates/servicepoint_binding_cs/ServicePoint/ServicePointExtensions.cs similarity index 100% rename from crates/servicepoint_binding_cs/src/ServicePointExtensions.cs rename to crates/servicepoint_binding_cs/ServicePoint/ServicePointExtensions.cs diff --git a/crates/servicepoint_binding_cs/src/SpNativeInstance.cs b/crates/servicepoint_binding_cs/ServicePoint/SpNativeInstance.cs similarity index 100% rename from crates/servicepoint_binding_cs/src/SpNativeInstance.cs rename to crates/servicepoint_binding_cs/ServicePoint/SpNativeInstance.cs diff --git a/crates/servicepoint_binding_cs/build.rs b/crates/servicepoint_binding_cs/build.rs index 23a0377..ec5aa81 100644 --- a/crates/servicepoint_binding_cs/build.rs +++ b/crates/servicepoint_binding_cs/build.rs @@ -1,19 +1,28 @@ fn main() { - println!("cargo:rerun-if-changed=DOESNOTEXIST"); // rebuild every time + println!("cargo:rerun-if-changed=../servicepoint_binding_c/src"); + println!("cargo:rerun-if-changed=build.rs"); csbindgen::Builder::default() + .input_extern_file("../servicepoint_binding_c/src/bit_vec.rs") + .input_extern_file("../servicepoint_binding_c/src/byte_grid.rs") + .input_extern_file("../servicepoint_binding_c/src/command.rs") + .input_extern_file("../servicepoint_binding_c/src/connection.rs") + .input_extern_file("../servicepoint_binding_c/src/pixel_grid.rs") + .input_extern_file("../servicepoint_binding_c/src/lib.rs") + .input_extern_file("../servicepoint_binding_c/src/c_slice.rs") + .input_extern_file("../servicepoint_binding_c/src/packet.rs") .input_extern_file("../servicepoint/src/bit_vec.rs") .input_extern_file("../servicepoint/src/byte_grid.rs") .input_extern_file("../servicepoint/src/command.rs") - .input_extern_file("../servicepoint/src/compression_code.rs") .input_extern_file("../servicepoint/src/connection.rs") .input_extern_file("../servicepoint/src/pixel_grid.rs") .input_extern_file("../servicepoint/src/lib.rs") - .input_extern_file("../servicepoint/src/c_slice.rs") .input_extern_file("../servicepoint/src/packet.rs") - .csharp_dll_name("servicepoint") + .input_extern_file("../servicepoint/src/compression_code.rs") + .csharp_dll_name("servicepoint_binding_c") .csharp_namespace("ServicePoint.BindGen") .csharp_use_nint_types(true) .csharp_class_accessibility("public") - .generate_csharp_file("src/BindGen/ServicePoint.g.cs") + .csharp_generate_const_filter(|_| true) + .generate_csharp_file("ServicePoint/BindGen/ServicePoint.g.cs") .unwrap(); } diff --git a/examples/lang_c/Makefile b/examples/lang_c/Makefile index 825510a..787d38e 100644 --- a/examples/lang_c/Makefile +++ b/examples/lang_c/Makefile @@ -15,22 +15,19 @@ run: out/lang_c PHONY: build clean dependencies run out/lang_c: dependencies src/main.c - mkdir out || true + mkdir -p out || true ${CC} src/main.c \ -I include \ -L $(REPO_ROOT)/target/release \ - -Wl,-Bstatic -lservicepoint \ + -Wl,-Bstatic -lservicepoint_binding_c \ -Wl,-Bdynamic -llzma \ - -o out/lang_c \ + -o out/lang_c dependencies: FORCE - mkdir include || true - # generate servicepoint header + mkdir -p include || true + # generate servicepoint header and binary to link against SERVICEPOINT_HEADER_OUT=$(THIS_DIR)/include cargo build \ - --manifest-path=$(REPO_ROOT)/crates/servicepoint_binding_c/Cargo.toml - - # build release binary to link against - cargo build --manifest-path=$(REPO_ROOT)/crates/servicepoint/Cargo.toml --release \ - --features c_api,all_compressions + --manifest-path=$(REPO_ROOT)/crates/servicepoint_binding_c/Cargo.toml \ + --release FORCE: ; diff --git a/examples/lang_c/build.rs b/examples/lang_c/build.rs index 56b5b89..279439f 100644 --- a/examples/lang_c/build.rs +++ b/examples/lang_c/build.rs @@ -1,11 +1,12 @@ -fn main() { - println!("cargo::rerun-if-changed=src/main.c"); - println!("cargo::rerun-if-changed=build.rs"); +const SP_INCLUDE: &str = "DEP_SERVICEPOINT_INCLUDE"; - let sp_include = std::env::var_os("DEP_SERVICEPOINT_INCLUDE") - .unwrap() - .into_string() - .unwrap(); +fn main() { + println!("cargo:rerun-if-changed=src/main.c"); + println!("cargo:rerun-if-changed=build.rs"); + println!("cargo:rerun-if-env-changed={SP_INCLUDE}"); + + let sp_include = + std::env::var_os(SP_INCLUDE).unwrap().into_string().unwrap(); // this builds a lib, this is only to check that the example compiles let mut cc = cc::Build::new(); diff --git a/examples/lang_c/include/servicepoint.h b/examples/lang_c/include/servicepoint.h index 694409d..cc1e903 100644 --- a/examples/lang_c/include/servicepoint.h +++ b/examples/lang_c/include/servicepoint.h @@ -9,95 +9,87 @@ /** * pixel count on whole screen */ -#define sp2_PIXEL_COUNT (sp2_PIXEL_WIDTH * sp2_PIXEL_HEIGHT) +#define sp_PIXEL_COUNT (sp_PIXEL_WIDTH * sp_PIXEL_HEIGHT) /** * screen height in pixels */ -#define sp2_PIXEL_HEIGHT (sp2_TILE_HEIGHT * sp2_TILE_SIZE) +#define sp_PIXEL_HEIGHT (sp_TILE_HEIGHT * sp_TILE_SIZE) /** * screen width in pixels */ -#define sp2_PIXEL_WIDTH (sp2_TILE_WIDTH * sp2_TILE_SIZE) +#define sp_PIXEL_WIDTH (sp_TILE_WIDTH * sp_TILE_SIZE) /** * tile count in the y-direction */ -#define sp2_TILE_HEIGHT 20 +#define sp_TILE_HEIGHT 20 /** * size of a single tile in one dimension */ -#define sp2_TILE_SIZE 8 +#define sp_TILE_SIZE 8 /** * tile count in the x-direction */ -#define sp2_TILE_WIDTH 56 +#define sp_TILE_WIDTH 56 /** * Specifies the kind of compression to use. Availability depends on features. */ -enum sp2_CompressionCode +enum sp_CompressionCode #ifdef __cplusplus : uint16_t #endif // __cplusplus { Uncompressed = 0, -#if defined(SP2_FEATURE_compression_zlib) Zlib = 26490, -#endif -#if defined(SP2_FEATURE_compression_bzip2) Bzip2 = 25210, -#endif -#if defined(SP2_FEATURE_compression_lzma) Lzma = 27770, -#endif -#if defined(SP2_FEATURE_compression_zstd) Zstd = 31347, -#endif }; #ifndef __cplusplus -typedef uint16_t sp2_CompressionCode; +typedef uint16_t sp_CompressionCode; #endif // __cplusplus /** * A vector of bits */ -typedef struct sp2_BitVec sp2_BitVec; +typedef struct sp_BitVec sp_BitVec; /** * A 2D grid of bytes */ -typedef struct sp2_ByteGrid sp2_ByteGrid; +typedef struct sp_ByteGrid sp_ByteGrid; /** * A command to send to the display. */ -typedef struct sp2_Command sp2_Command; +typedef struct sp_Command sp_Command; /** * A connection to the display. */ -typedef struct sp2_Connection sp2_Connection; +typedef struct sp_Connection sp_Connection; /** * The raw packet. Should probably not be used directly. */ -typedef struct sp2_Packet sp2_Packet; +typedef struct sp_Packet sp_Packet; /** * A grid of pixels stored in packed bytes. */ -typedef struct sp2_PixelGrid sp2_PixelGrid; +typedef struct sp_PixelGrid sp_PixelGrid; /** * Represents a span of memory (`&mut [u8]` ) as a struct usable by C code. * * Usage of this type is inherently unsafe. */ -typedef struct sp2_CByteSlice { +typedef struct sp_CByteSlice { /** * The start address of the memory */ @@ -106,17 +98,17 @@ typedef struct sp2_CByteSlice { * The amount of memory in bytes */ size_t length; -} sp2_CByteSlice; +} sp_CByteSlice; /** * Type alias for documenting the meaning of the u16 in enum values */ -typedef size_t sp2_Offset; +typedef size_t sp_Offset; /** * Type alias for documenting the meaning of the u16 in enum values */ -typedef uint8_t sp2_Brightness; +typedef uint8_t sp_Brightness; #ifdef __cplusplus extern "C" { @@ -126,51 +118,51 @@ extern "C" { * Clones a `BitVec`. * The returned instance has to be freed with `bit_vec_dealloc`. */ -struct sp2_BitVec *sp2_bit_vec_clone(const struct sp2_BitVec *this_); +struct sp_BitVec *sp_bit_vec_clone(const struct sp_BitVec *this_); /** * Deallocates a `BitVec`. * * Note: do not call this if the grid has been consumed in another way, e.g. to create a command. */ -void sp2_bit_vec_dealloc(struct sp2_BitVec *this_); +void sp_bit_vec_dealloc(struct sp_BitVec *this_); /** * Sets the value of all bits in the `BitVec`. */ -void sp2_bit_vec_fill(struct sp2_BitVec *this_, bool value); +void sp_bit_vec_fill(struct sp_BitVec *this_, bool value); /** * Gets the value of a bit from the `BitVec`. */ -bool sp2_bit_vec_get(const struct sp2_BitVec *this_, size_t index); +bool sp_bit_vec_get(const struct sp_BitVec *this_, size_t index); /** * Returns true if length is 0. */ -bool sp2_bit_vec_is_empty(const struct sp2_BitVec *this_); +bool sp_bit_vec_is_empty(const struct sp_BitVec *this_); /** * Gets the length of the `BitVec` in bits. */ -size_t sp2_bit_vec_len(const struct sp2_BitVec *this_); +size_t sp_bit_vec_len(const struct sp_BitVec *this_); /** * Loads a `BitVec` from the provided data. * The returned instance has to be freed with `bit_vec_dealloc`. */ -struct sp2_BitVec *sp2_bit_vec_load(const uint8_t *data, size_t data_length); +struct sp_BitVec *sp_bit_vec_load(const uint8_t *data, size_t data_length); /** * Creates a new `BitVec` instance. * The returned instance has to be freed with `bit_vec_dealloc`. */ -struct sp2_BitVec *sp2_bit_vec_new(size_t size); +struct sp_BitVec *sp_bit_vec_new(size_t size); /** * Sets the value of a bit in the `BitVec`. */ -bool sp2_bit_vec_set(struct sp2_BitVec *this_, size_t index, bool value); +bool sp_bit_vec_set(struct sp_BitVec *this_, size_t index, bool value); /** * Gets an unsafe reference to the data of the `BitVec` instance. @@ -183,58 +175,58 @@ bool sp2_bit_vec_set(struct sp2_BitVec *this_, size_t index, bool value); * Reading and writing concurrently to either the original instance or the returned data will * result in undefined behavior. */ -struct sp2_CByteSlice sp2_bit_vec_unsafe_data_ref(struct sp2_BitVec *this_); +struct sp_CByteSlice sp_bit_vec_unsafe_data_ref(struct sp_BitVec *this_); /** * Clones a `ByteGrid`. * The returned instance has to be freed with `byte_grid_dealloc`. */ -struct sp2_ByteGrid *sp2_byte_grid_clone(const struct sp2_ByteGrid *this_); +struct sp_ByteGrid *sp_byte_grid_clone(const struct sp_ByteGrid *this_); /** * Deallocates a `ByteGrid`. * * Note: do not call this if the grid has been consumed in another way, e.g. to create a command. */ -void sp2_byte_grid_dealloc(struct sp2_ByteGrid *this_); +void sp_byte_grid_dealloc(struct sp_ByteGrid *this_); /** * Fills the whole `ByteGrid` with the specified value */ -void sp2_byte_grid_fill(struct sp2_ByteGrid *this_, uint8_t value); +void sp_byte_grid_fill(struct sp_ByteGrid *this_, uint8_t value); /** * Get the current value at the specified position */ -uint8_t sp2_byte_grid_get(const struct sp2_ByteGrid *this_, size_t x, size_t y); +uint8_t sp_byte_grid_get(const struct sp_ByteGrid *this_, size_t x, size_t y); /** * Gets the height in pixels of the `ByteGrid` instance. */ -size_t sp2_byte_grid_height(const struct sp2_ByteGrid *this_); +size_t sp_byte_grid_height(const struct sp_ByteGrid *this_); /** * Loads a `ByteGrid` with the specified dimensions from the provided data. * The returned instance has to be freed with `byte_grid_dealloc`. */ -struct sp2_ByteGrid *sp2_byte_grid_load(size_t width, - size_t height, - const uint8_t *data, - size_t data_length); +struct sp_ByteGrid *sp_byte_grid_load(size_t width, + size_t height, + const uint8_t *data, + size_t data_length); /** * Creates a new `ByteGrid` instance. * The returned instance has to be freed with `byte_grid_dealloc`. */ -struct sp2_ByteGrid *sp2_byte_grid_new(size_t width, size_t height); +struct sp_ByteGrid *sp_byte_grid_new(size_t width, size_t height); /** * Sets the current value at the specified position */ -void sp2_byte_grid_set(struct sp2_ByteGrid *this_, - size_t x, - size_t y, - uint8_t value); +void sp_byte_grid_set(struct sp_ByteGrid *this_, + size_t x, + size_t y, + uint8_t value); /** * Gets an unsafe reference to the data of the `ByteGrid` instance. @@ -247,112 +239,112 @@ void sp2_byte_grid_set(struct sp2_ByteGrid *this_, * Reading and writing concurrently to either the original instance or the returned data will * result in undefined behavior. */ -struct sp2_CByteSlice sp2_byte_grid_unsafe_data_ref(struct sp2_ByteGrid *this_); +struct sp_CByteSlice sp_byte_grid_unsafe_data_ref(struct sp_ByteGrid *this_); /** * Gets the width in pixels of the `ByteGrid` instance. */ -size_t sp2_byte_grid_width(const struct sp2_ByteGrid *this_); +size_t sp_byte_grid_width(const struct sp_ByteGrid *this_); /** * Allocates a new `Command::BitmapLinear` instance. * The passed `BitVec` gets deallocated in the process. */ -struct sp2_Command *sp2_command_bitmap_linear(sp2_Offset offset, - struct sp2_BitVec *bit_vec, - sp2_CompressionCode compression); +struct sp_Command *sp_command_bitmap_linear(sp_Offset offset, + struct sp_BitVec *bit_vec, + sp_CompressionCode compression); /** * Allocates a new `Command::BitmapLinearAnd` instance. * The passed `BitVec` gets deallocated in the process. */ -struct sp2_Command *sp2_command_bitmap_linear_and(sp2_Offset offset, - struct sp2_BitVec *bit_vec, - sp2_CompressionCode compression); +struct sp_Command *sp_command_bitmap_linear_and(sp_Offset offset, + struct sp_BitVec *bit_vec, + sp_CompressionCode compression); /** * Allocates a new `Command::BitmapLinearOr` instance. * The passed `BitVec` gets deallocated in the process. */ -struct sp2_Command *sp2_command_bitmap_linear_or(sp2_Offset offset, - struct sp2_BitVec *bit_vec, - sp2_CompressionCode compression); +struct sp_Command *sp_command_bitmap_linear_or(sp_Offset offset, + struct sp_BitVec *bit_vec, + sp_CompressionCode compression); /** * Allocates a new `Command::BitmapLinearWin` instance. * The passed `PixelGrid` gets deallocated in the process. */ -struct sp2_Command *sp2_command_bitmap_linear_win(size_t x, - size_t y, - struct sp2_PixelGrid *byte_grid, - sp2_CompressionCode compression_code); +struct sp_Command *sp_command_bitmap_linear_win(size_t x, + size_t y, + struct sp_PixelGrid *byte_grid, + sp_CompressionCode compression_code); /** * Allocates a new `Command::BitmapLinearXor` instance. * The passed `BitVec` gets deallocated in the process. */ -struct sp2_Command *sp2_command_bitmap_linear_xor(sp2_Offset offset, - struct sp2_BitVec *bit_vec, - sp2_CompressionCode compression); +struct sp_Command *sp_command_bitmap_linear_xor(sp_Offset offset, + struct sp_BitVec *bit_vec, + sp_CompressionCode compression); /** * Allocates a new `Command::Brightness` instance */ -struct sp2_Command *sp2_command_brightness(sp2_Brightness brightness); +struct sp_Command *sp_command_brightness(sp_Brightness brightness); /** * Allocates a new `Command::CharBrightness` instance. * The passed `ByteGrid` gets deallocated in the process. */ -struct sp2_Command *sp2_command_char_brightness(size_t x, - size_t y, - struct sp2_ByteGrid *byte_grid); +struct sp_Command *sp_command_char_brightness(size_t x, + size_t y, + struct sp_ByteGrid *byte_grid); /** * Allocates a new `Command::Clear` instance */ -struct sp2_Command *sp2_command_clear(void); +struct sp_Command *sp_command_clear(void); /** * Clones a `Command` instance */ -struct sp2_Command *sp2_command_clone(const struct sp2_Command *original); +struct sp_Command *sp_command_clone(const struct sp_Command *original); /** * Allocates a new `Command::Cp437Data` instance. * The passed `ByteGrid` gets deallocated in the process. */ -struct sp2_Command *sp2_command_cp437_data(size_t x, - size_t y, - struct sp2_ByteGrid *byte_grid); +struct sp_Command *sp_command_cp437_data(size_t x, + size_t y, + struct sp_ByteGrid *byte_grid); /** * Deallocates a `Command`. Note that connection_send does this implicitly, so you only need * to do this if you use the library for parsing commands. */ -void sp2_command_dealloc(struct sp2_Command *ptr); +void sp_command_dealloc(struct sp_Command *ptr); /** * Allocates a new `Command::FadeOut` instance */ -struct sp2_Command *sp2_command_fade_out(void); +struct sp_Command *sp_command_fade_out(void); /** * Allocates a new `Command::HardReset` instance */ -struct sp2_Command *sp2_command_hard_reset(void); +struct sp_Command *sp_command_hard_reset(void); /** * Tries to turn a `Packet` into a `Command`. The packet is gets deallocated in the process. * * Returns: pointer to command or NULL */ -struct sp2_Command *sp2_command_try_from_packet(struct sp2_Packet *packet); +struct sp_Command *sp_command_try_from_packet(struct sp_Packet *packet); /** * Closes and deallocates a connection instance */ -void sp2_connection_dealloc(struct sp2_Connection *ptr); +void sp_connection_dealloc(struct sp_Connection *ptr); /** * Creates a new instance of Connection. @@ -362,83 +354,83 @@ void sp2_connection_dealloc(struct sp2_Connection *ptr); * * Panics: bad string encoding */ -struct sp2_Connection *sp2_connection_open(const char *host); +struct sp_Connection *sp_connection_open(const char *host); /** * Sends the command instance. The instance is consumed / destroyed and cannot be used after this call. */ -bool sp2_connection_send(const struct sp2_Connection *connection, - struct sp2_Packet *command_ptr); +bool sp_connection_send(const struct sp_Connection *connection, + struct sp_Packet *command_ptr); /** * Deallocates a `Packet`. * * Note: do not call this if the instance has been consumed in another way, e.g. by sending it. */ -void sp2_packet_dealloc(struct sp2_Packet *this_); +void sp_packet_dealloc(struct sp_Packet *this_); /** * Turns a `Command` into a `Packet`. The command gets deallocated in the process. */ -struct sp2_Packet *sp2_packet_from_command(struct sp2_Command *command); +struct sp_Packet *sp_packet_from_command(struct sp_Command *command); /** * Tries to load a `Packet` from the passed array with the specified length. * * returns: NULL in case of an error, pointer to the allocated packet otherwise */ -struct sp2_Packet *sp2_packet_try_load(const uint8_t *data, size_t length); +struct sp_Packet *sp_packet_try_load(const uint8_t *data, size_t length); /** * Clones a `PixelGrid`. * The returned instance has to be freed with `pixel_grid_dealloc`. */ -struct sp2_PixelGrid *sp2_pixel_grid_clone(const struct sp2_PixelGrid *this_); +struct sp_PixelGrid *sp_pixel_grid_clone(const struct sp_PixelGrid *this_); /** * Deallocates a `PixelGrid`. * * Note: do not call this if the grid has been consumed in another way, e.g. to create a command. */ -void sp2_pixel_grid_dealloc(struct sp2_PixelGrid *this_); +void sp_pixel_grid_dealloc(struct sp_PixelGrid *this_); /** * Fills the whole `PixelGrid` with the specified value */ -void sp2_pixel_grid_fill(struct sp2_PixelGrid *this_, bool value); +void sp_pixel_grid_fill(struct sp_PixelGrid *this_, bool value); /** * Get the current value at the specified position */ -bool sp2_pixel_grid_get(const struct sp2_PixelGrid *this_, size_t x, size_t y); +bool sp_pixel_grid_get(const struct sp_PixelGrid *this_, size_t x, size_t y); /** * Gets the height in pixels of the `PixelGrid` instance. */ -size_t sp2_pixel_grid_height(const struct sp2_PixelGrid *this_); +size_t sp_pixel_grid_height(const struct sp_PixelGrid *this_); /** * Loads a `PixelGrid` with the specified dimensions from the provided data. * The returned instance has to be freed with `pixel_grid_dealloc`. */ -struct sp2_PixelGrid *sp2_pixel_grid_load(size_t width, - size_t height, - const uint8_t *data, - size_t data_length); +struct sp_PixelGrid *sp_pixel_grid_load(size_t width, + size_t height, + const uint8_t *data, + size_t data_length); /** * Creates a new `PixelGrid` instance. * The returned instance has to be freed with `pixel_grid_dealloc`. */ -struct sp2_PixelGrid *sp2_pixel_grid_new(size_t width, size_t height); +struct sp_PixelGrid *sp_pixel_grid_new(size_t width, size_t height); /** * Sets the current value at the specified position */ -void sp2_pixel_grid_set(struct sp2_PixelGrid *this_, - size_t x, - size_t y, - bool value); +void sp_pixel_grid_set(struct sp_PixelGrid *this_, + size_t x, + size_t y, + bool value); /** * Gets an unsafe reference to the data of the `PixelGrid` instance. @@ -451,12 +443,12 @@ void sp2_pixel_grid_set(struct sp2_PixelGrid *this_, * Reading and writing concurrently to either the original instance or the returned data will * result in undefined behavior. */ -struct sp2_CByteSlice sp2_pixel_grid_unsafe_data_ref(struct sp2_PixelGrid *this_); +struct sp_CByteSlice sp_pixel_grid_unsafe_data_ref(struct sp_PixelGrid *this_); /** * Gets the width in pixels of the `PixelGrid` instance. */ -size_t sp2_pixel_grid_width(const struct sp2_PixelGrid *this_); +size_t sp_pixel_grid_width(const struct sp_PixelGrid *this_); #ifdef __cplusplus } // extern "C" diff --git a/examples/lang_c/src/main.c b/examples/lang_c/src/main.c index 7077eff..3951293 100644 --- a/examples/lang_c/src/main.c +++ b/examples/lang_c/src/main.c @@ -2,18 +2,18 @@ #include "servicepoint.h" int main(void) { - sp2_Connection *connection = sp2_connection_open("localhost:2342"); + sp_Connection *connection = sp_connection_open("localhost:2342"); if (connection == NULL) return 1; - sp2_PixelGrid *pixels = sp2_pixel_grid_new(sp2_PIXEL_WIDTH, sp2_PIXEL_HEIGHT); - sp2_pixel_grid_fill(pixels, true); + sp_PixelGrid *pixels = sp_pixel_grid_new(sp_PIXEL_WIDTH, sp_PIXEL_HEIGHT); + sp_pixel_grid_fill(pixels, true); - sp2_Command *command = sp2_command_bitmap_linear_win(0, 0, pixels, Uncompressed); - sp2_Packet *packet = sp2_packet_from_command(command); - if (!sp2_connection_send(connection, packet)) + sp_Command *command = sp_command_bitmap_linear_win(0, 0, pixels, Uncompressed); + sp_Packet *packet = sp_packet_from_command(command); + if (!sp_connection_send(connection, packet)) return 1; - sp2_connection_dealloc(connection); + sp_connection_dealloc(connection); return 0; } diff --git a/examples/lang_cs/lang_cs.csproj b/examples/lang_cs/lang_cs.csproj index d4fed5f..5ad0986 100644 --- a/examples/lang_cs/lang_cs.csproj +++ b/examples/lang_cs/lang_cs.csproj @@ -9,7 +9,7 @@ - +