replace bit_vec module with bitvec library
This commit is contained in:
		
							parent
							
								
									c600761f29
								
							
						
					
					
						commit
						947a3fe60e
					
				
					 16 changed files with 187 additions and 369 deletions
				
			
		
							
								
								
									
										40
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										40
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							|  | @ -95,6 +95,18 @@ version = "2.5.0" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "bitvec" | ||||
| version = "1.0.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" | ||||
| dependencies = [ | ||||
|  "funty", | ||||
|  "radium", | ||||
|  "tap", | ||||
|  "wyz", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "bzip2" | ||||
| version = "0.4.4" | ||||
|  | @ -267,6 +279,12 @@ dependencies = [ | |||
|  "miniz_oxide", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "funty" | ||||
| version = "2.0.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "getrandom" | ||||
| version = "0.2.15" | ||||
|  | @ -419,6 +437,12 @@ dependencies = [ | |||
|  "proc-macro2", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "radium" | ||||
| version = "0.7.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "rand" | ||||
| version = "0.8.5" | ||||
|  | @ -542,6 +566,7 @@ dependencies = [ | |||
| name = "servicepoint" | ||||
| version = "0.5.1" | ||||
| dependencies = [ | ||||
|  "bitvec", | ||||
|  "bzip2", | ||||
|  "clap 4.5.4", | ||||
|  "flate2", | ||||
|  | @ -602,6 +627,12 @@ dependencies = [ | |||
|  "unicode-ident", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "tap" | ||||
| version = "1.0.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "tempfile" | ||||
| version = "3.10.1" | ||||
|  | @ -766,6 +797,15 @@ version = "0.52.5" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "wyz" | ||||
| version = "0.5.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" | ||||
| dependencies = [ | ||||
|  "tap", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "zstd" | ||||
| version = "0.13.1" | ||||
|  |  | |||
|  | @ -14,6 +14,7 @@ crate-type = ["rlib"] | |||
| 
 | ||||
| [dependencies] | ||||
| log = "0.4" | ||||
| bitvec = "1.0" | ||||
| flate2 = { version = "1.0", optional = true } | ||||
| bzip2 = { version = "0.4", optional = true } | ||||
| zstd = { version = "0.13", optional = true } | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ use std::time::Duration; | |||
| 
 | ||||
| use clap::Parser; | ||||
| 
 | ||||
| use servicepoint::*; | ||||
| use servicepoint::{bitvec::prelude::BitVec, *}; | ||||
| 
 | ||||
| #[derive(Parser, Debug)] | ||||
| struct Cli { | ||||
|  | @ -34,7 +34,7 @@ fn main() { | |||
| 
 | ||||
|         // this works because the pixel grid has max size
 | ||||
|         let pixel_data: Vec<u8> = enabled_pixels.clone().into(); | ||||
|         let bit_vec = BitVec::from(&*pixel_data); | ||||
|         let bit_vec = BitVec::from_vec(pixel_data); | ||||
| 
 | ||||
|         connection | ||||
|             .send(Command::BitmapLinearAnd(0, bit_vec, CompressionCode::Lzma)) | ||||
|  |  | |||
|  | @ -1,257 +0,0 @@ | |||
| use crate::DataRef; | ||||
| 
 | ||||
| /// A fixed-size vector of bits
 | ||||
| #[derive(Debug, Clone, PartialEq)] | ||||
| pub struct BitVec { | ||||
|     size: usize, | ||||
|     data: Vec<u8>, | ||||
| } | ||||
| 
 | ||||
| impl BitVec { | ||||
|     /// Create a new `BitVec`.
 | ||||
|     ///
 | ||||
|     /// # Arguments
 | ||||
|     ///
 | ||||
|     /// * `size`: size in bits.
 | ||||
|     ///
 | ||||
|     /// returns: `BitVec` with all bits set to false.
 | ||||
|     ///
 | ||||
|     /// # Panics
 | ||||
|     ///
 | ||||
|     /// When `size` is not divisible by 8.
 | ||||
|     #[must_use] | ||||
|     pub fn new(size: usize) -> BitVec { | ||||
|         assert_eq!(size % 8, 0); | ||||
|         Self { | ||||
|             size, | ||||
|             data: vec![0; size / 8], | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Sets the value of a bit.
 | ||||
|     ///
 | ||||
|     /// # Arguments
 | ||||
|     ///
 | ||||
|     /// * `index`: the bit index to edit
 | ||||
|     /// * `value`: the value to set the bit to
 | ||||
|     ///
 | ||||
|     /// returns: old value of the bit
 | ||||
|     ///
 | ||||
|     /// # Panics
 | ||||
|     ///
 | ||||
|     /// When accessing `index` out of bounds.
 | ||||
|     pub fn set(&mut self, index: usize, value: bool) -> bool { | ||||
|         let (byte_index, bit_mask) = self.get_indexes(index); | ||||
| 
 | ||||
|         let byte = self.data[byte_index]; | ||||
|         let old_value = byte & bit_mask != 0; | ||||
| 
 | ||||
|         self.data[byte_index] = if value { | ||||
|             byte | bit_mask | ||||
|         } else { | ||||
|             byte & (u8::MAX ^ bit_mask) | ||||
|         }; | ||||
| 
 | ||||
|         old_value | ||||
|     } | ||||
| 
 | ||||
|     /// Gets the value of a bit.
 | ||||
|     ///
 | ||||
|     /// # Arguments
 | ||||
|     ///
 | ||||
|     /// * `index`: the bit index to read
 | ||||
|     ///
 | ||||
|     /// returns: value of the bit
 | ||||
|     ///
 | ||||
|     /// # Panics
 | ||||
|     ///
 | ||||
|     /// When accessing `index` out of bounds.
 | ||||
|     #[must_use] | ||||
|     pub fn get(&self, index: usize) -> bool { | ||||
|         let (byte_index, bit_mask) = self.get_indexes(index); | ||||
|         self.data[byte_index] & bit_mask != 0 | ||||
|     } | ||||
| 
 | ||||
|     /// Sets all bits to the specified value
 | ||||
|     ///
 | ||||
|     /// # Arguments
 | ||||
|     ///
 | ||||
|     /// * `value`: the value to set all bits to
 | ||||
|     ///
 | ||||
|     /// # Examples
 | ||||
|     /// ```
 | ||||
|     ///  use servicepoint::BitVec;
 | ||||
|     ///  let mut vec = BitVec::new(8);
 | ||||
|     ///  vec.fill(true);
 | ||||
|     /// ```
 | ||||
|     pub fn fill(&mut self, value: bool) { | ||||
|         let byte: u8 = if value { 0xFF } else { 0x00 }; | ||||
|         self.data.fill(byte); | ||||
|     } | ||||
| 
 | ||||
|     /// Gets the length in bits
 | ||||
|     #[must_use] | ||||
|     pub fn len(&self) -> usize { | ||||
|         self.size | ||||
|     } | ||||
| 
 | ||||
|     /// returns true if length is 0.
 | ||||
|     #[must_use] | ||||
|     pub fn is_empty(&self) -> bool { | ||||
|         self.data.is_empty() | ||||
|     } | ||||
| 
 | ||||
|     /// Get an iterator over every bit in the vector
 | ||||
|     pub fn iter(&self) -> Iter { | ||||
|         Iter { | ||||
|             bit_vec: self, | ||||
|             index: 0, | ||||
|             end: self.size, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Calculates the byte index and bitmask for a specific bit in the vector
 | ||||
|     fn get_indexes(&self, bit_index: usize) -> (usize, u8) { | ||||
|         assert!( | ||||
|             bit_index < self.size, | ||||
|             "bit index {bit_index} is outside of range 0..<{}", | ||||
|             self.size | ||||
|         ); | ||||
| 
 | ||||
|         let byte_index = bit_index / 8; | ||||
|         let bit_in_byte_index = 7 - bit_index % 8; | ||||
|         let bit_mask: u8 = 1 << bit_in_byte_index; | ||||
|         (byte_index, bit_mask) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl DataRef for BitVec { | ||||
|     fn data_ref_mut(&mut self) -> &mut [u8] { | ||||
|         self.data.as_mut_slice() | ||||
|     } | ||||
| 
 | ||||
|     fn data_ref(&self) -> &[u8] { | ||||
|         self.data.as_slice() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<BitVec> for Vec<u8> { | ||||
|     /// Turns the `BitVec` into the underlying `Vec<u8>`
 | ||||
|     fn from(value: BitVec) -> Self { | ||||
|         value.data | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<&[u8]> for BitVec { | ||||
|     /// Interpret the data as a series of bits and load then into a new `BitVec` instance.
 | ||||
|     fn from(value: &[u8]) -> Self { | ||||
|         Self { | ||||
|             size: value.len() * 8, | ||||
|             data: Vec::from(value), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct Iter<'t> { | ||||
|     pub(crate) bit_vec: &'t BitVec, | ||||
|     pub(crate) index: usize, | ||||
|     pub(crate) end: usize, | ||||
| } | ||||
| 
 | ||||
| impl<'t> Iterator for Iter<'t> { | ||||
|     type Item = bool; | ||||
| 
 | ||||
|     fn next(&mut self) -> Option<Self::Item> { | ||||
|         if self.index >= self.end { | ||||
|             return None; | ||||
|         } | ||||
| 
 | ||||
|         let result = Some(self.bit_vec.get(self.index)); | ||||
|         self.index += 1; | ||||
|         result | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use crate::{BitVec, DataRef}; | ||||
| 
 | ||||
|     #[test] | ||||
|     fn fill() { | ||||
|         let mut vec = BitVec::new(8 * 3); | ||||
|         assert_eq!(vec.data, [0x00, 0x00, 0x00]); | ||||
| 
 | ||||
|         vec.fill(true); | ||||
|         assert_eq!(vec.data, [0xFF, 0xFF, 0xFF]); | ||||
| 
 | ||||
|         vec.fill(false); | ||||
|         assert_eq!(vec.data, [0x00, 0x00, 0x00]); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn get_set() { | ||||
|         let mut vec = BitVec::new(8 * 3); | ||||
|         assert!(!vec.get(1)); | ||||
|         assert!(!vec.get(11)); | ||||
| 
 | ||||
|         vec.set(1, true); | ||||
|         vec.set(11, true); | ||||
|         assert_eq!(vec.data, [0x40, 0x10, 0x00]); | ||||
|         assert!(!vec.get(0)); | ||||
|         assert!(vec.get(1)); | ||||
|         assert!(vec.get(11)); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn load() { | ||||
|         let mut vec = BitVec::new(8 * 3); | ||||
|         vec.set(6, true); | ||||
|         vec.set(7, true); | ||||
|         vec.set(8, true); | ||||
|         vec.set(9, true); | ||||
|         vec.set(10, true); | ||||
|         vec.set(vec.len() - 1, true); | ||||
| 
 | ||||
|         assert_eq!(vec.data, [0x03, 0xE0, 0x01]); | ||||
| 
 | ||||
|         let data: Vec<u8> = vec.into(); | ||||
| 
 | ||||
|         let vec = BitVec::from(&*data); | ||||
|         assert_eq!(vec.data, [0x03, 0xE0, 0x01]); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn mut_data_ref() { | ||||
|         let mut vec = BitVec::new(8 * 3); | ||||
| 
 | ||||
|         let data_ref = vec.data_ref_mut(); | ||||
|         data_ref.copy_from_slice(&[0x40, 0x10, 0x00]); | ||||
| 
 | ||||
|         assert_eq!(vec.data, [0x40, 0x10, 0x00]); | ||||
|         assert!(vec.get(1)); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn is_empty() { | ||||
|         let vec = BitVec::new(8 * 3); | ||||
|         assert!(!vec.is_empty()); | ||||
| 
 | ||||
|         let vec = BitVec::new(0); | ||||
|         assert!(vec.is_empty()); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn get_returns_old() { | ||||
|         let mut vec = BitVec::new(8); | ||||
|         assert!(!vec.set(1, true)); | ||||
|         assert!(vec.set(1, true)); | ||||
|         assert!(vec.set(1, false)); | ||||
|         assert!(!vec.set(1, false)); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn debug_print() { | ||||
|         let vec = BitVec::new(8 * 3); | ||||
|         format!("{vec:?}"); | ||||
|     } | ||||
| } | ||||
|  | @ -85,17 +85,12 @@ impl Grid<u8> for ByteGrid { | |||
|     /// * `x` and `y`: position of the cell
 | ||||
|     /// * `value`: the value to write to the cell
 | ||||
|     ///
 | ||||
|     /// returns: old value of the cell.
 | ||||
|     ///
 | ||||
|     /// # Panics
 | ||||
|     ///
 | ||||
|     /// When accessing `x` or `y` out of bounds.
 | ||||
|     fn set(&mut self, x: usize, y: usize, value: u8) -> u8 { | ||||
|     fn set(&mut self, x: usize, y: usize, value: u8) { | ||||
|         self.check_indexes(x, y); | ||||
|         let pos = &mut self.data[x + y * self.width]; | ||||
|         let old_val = *pos; | ||||
|         *pos = value; | ||||
|         old_val | ||||
|         self.data[x + y * self.width] = value; | ||||
|     } | ||||
| 
 | ||||
|     /// Gets the current value at the specified position.
 | ||||
|  |  | |||
|  | @ -1,7 +1,9 @@ | |||
| use bitvec::prelude::{BitVec, Msb0}; | ||||
| 
 | ||||
| use crate::command_code::CommandCode; | ||||
| use crate::compression::{into_compressed, into_decompressed}; | ||||
| use crate::{ | ||||
|     BitVec, ByteGrid, CompressionCode, Grid, Header, Packet, PixelGrid, | ||||
|     ByteGrid, CompressionCode, Grid, Header, Packet, PixelGrid, SpBitVec, | ||||
|     TILE_SIZE, | ||||
| }; | ||||
| 
 | ||||
|  | @ -25,6 +27,7 @@ pub type Offset = usize; | |||
| /// Type alias for documenting the meaning of the u16 in enum values
 | ||||
| pub type Brightness = u8; | ||||
| 
 | ||||
| // TODO: check order
 | ||||
| /// A command to send to the display.
 | ||||
| #[derive(Debug, Clone, PartialEq)] | ||||
| pub enum Command { | ||||
|  | @ -43,16 +46,16 @@ pub enum Command { | |||
|     BitmapLegacy, | ||||
|     /// Set pixel data starting at the offset.
 | ||||
|     /// The contained `BitVec` is always uncompressed.
 | ||||
|     BitmapLinear(Offset, BitVec, CompressionCode), | ||||
|     BitmapLinear(Offset, SpBitVec, CompressionCode), | ||||
|     /// Set pixel data according to an and-mask starting at the offset.
 | ||||
|     /// The contained `BitVec` is always uncompressed.
 | ||||
|     BitmapLinearAnd(Offset, BitVec, CompressionCode), | ||||
|     BitmapLinearAnd(Offset, SpBitVec, CompressionCode), | ||||
|     /// Set pixel data according to an or-mask starting at the offset.
 | ||||
|     /// The contained `BitVec` is always uncompressed.
 | ||||
|     BitmapLinearOr(Offset, BitVec, CompressionCode), | ||||
|     BitmapLinearOr(Offset, SpBitVec, CompressionCode), | ||||
|     /// Set pixel data according to a xor-mask starting at the offset.
 | ||||
|     /// The contained `BitVec` is always uncompressed.
 | ||||
|     BitmapLinearXor(Offset, BitVec, CompressionCode), | ||||
|     BitmapLinearXor(Offset, SpBitVec, CompressionCode), | ||||
|     /// Show text on the screen. Note that the byte data has to be CP437 encoded.
 | ||||
|     Cp437Data(Origin, ByteGrid), | ||||
|     /// Sets a window of pixels to the specified values
 | ||||
|  | @ -366,7 +369,7 @@ impl Command { | |||
|     /// Helper method for Packets into `BitMapLinear*`-Commands
 | ||||
|     fn packet_into_linear_bitmap( | ||||
|         packet: Packet, | ||||
|     ) -> Result<(BitVec, CompressionCode), TryFromPacketError> { | ||||
|     ) -> Result<(BitVec<u8, Msb0>, CompressionCode), TryFromPacketError> { | ||||
|         let Packet(Header(_, _, length, sub, reserved), payload) = packet; | ||||
|         if reserved != 0 { | ||||
|             return Err(TryFromPacketError::ExtraneousHeaderValues); | ||||
|  | @ -387,17 +390,18 @@ impl Command { | |||
|                 payload.len(), | ||||
|             )); | ||||
|         } | ||||
|         Ok((BitVec::from(&*payload), sub)) | ||||
|         Ok((BitVec::from_vec(payload), sub)) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use bitvec::prelude::BitVec; | ||||
| 
 | ||||
|     use crate::command::TryFromPacketError; | ||||
|     use crate::command_code::CommandCode; | ||||
|     use crate::{ | ||||
|         BitVec, ByteGrid, Command, CompressionCode, Grid, Header, Origin, | ||||
|         Packet, PixelGrid, | ||||
|         ByteGrid, Command, CompressionCode, Header, Origin, Packet, PixelGrid, | ||||
|     }; | ||||
| 
 | ||||
|     fn round_trip(original: Command) { | ||||
|  | @ -462,20 +466,24 @@ mod tests { | |||
|     #[test] | ||||
|     fn round_trip_bitmap_linear() { | ||||
|         for compression in all_compressions().to_owned() { | ||||
|             round_trip(Command::BitmapLinear(23, BitVec::new(40), compression)); | ||||
|             round_trip(Command::BitmapLinear( | ||||
|                 23, | ||||
|                 BitVec::repeat(false, 40), | ||||
|                 compression, | ||||
|             )); | ||||
|             round_trip(Command::BitmapLinearAnd( | ||||
|                 23, | ||||
|                 BitVec::new(40), | ||||
|                 BitVec::repeat(false, 40), | ||||
|                 compression, | ||||
|             )); | ||||
|             round_trip(Command::BitmapLinearOr( | ||||
|                 23, | ||||
|                 BitVec::new(40), | ||||
|                 BitVec::repeat(false, 40), | ||||
|                 compression, | ||||
|             )); | ||||
|             round_trip(Command::BitmapLinearXor( | ||||
|                 23, | ||||
|                 BitVec::new(40), | ||||
|                 BitVec::repeat(false, 40), | ||||
|                 compression, | ||||
|             )); | ||||
|             round_trip(Command::BitmapLinearWin( | ||||
|  | @ -590,8 +598,12 @@ mod tests { | |||
|     #[test] | ||||
|     fn error_decompression_failed_and() { | ||||
|         for compression in all_compressions().to_owned() { | ||||
|             let p: Packet = | ||||
|                 Command::BitmapLinearAnd(0, BitVec::new(8), compression).into(); | ||||
|             let p: Packet = Command::BitmapLinearAnd( | ||||
|                 0, | ||||
|                 BitVec::repeat(false, 8), | ||||
|                 compression, | ||||
|             ) | ||||
|             .into(); | ||||
|             let Packet(header, mut payload) = p; | ||||
| 
 | ||||
|             // mangle it
 | ||||
|  | @ -633,7 +645,7 @@ mod tests { | |||
|     fn error_reserved_used() { | ||||
|         let Packet(header, payload) = Command::BitmapLinear( | ||||
|             0, | ||||
|             BitVec::new(8), | ||||
|             BitVec::repeat(false, 8), | ||||
|             CompressionCode::Uncompressed, | ||||
|         ) | ||||
|         .into(); | ||||
|  | @ -649,7 +661,7 @@ mod tests { | |||
|     fn error_invalid_compression() { | ||||
|         let Packet(header, payload) = Command::BitmapLinear( | ||||
|             0, | ||||
|             BitVec::new(8), | ||||
|             BitVec::repeat(false, 8), | ||||
|             CompressionCode::Uncompressed, | ||||
|         ) | ||||
|         .into(); | ||||
|  | @ -665,7 +677,7 @@ mod tests { | |||
|     fn error_unexpected_size() { | ||||
|         let Packet(header, payload) = Command::BitmapLinear( | ||||
|             0, | ||||
|             BitVec::new(8), | ||||
|             BitVec::repeat(false, 8), | ||||
|             CompressionCode::Uncompressed, | ||||
|         ) | ||||
|         .into(); | ||||
|  |  | |||
|  | @ -6,12 +6,10 @@ pub trait Grid<T> { | |||
|     ///
 | ||||
|     /// * `x` and `y`: position of the cell to read
 | ||||
|     ///
 | ||||
|     /// returns: the old value
 | ||||
|     ///
 | ||||
|     /// # Panics
 | ||||
|     ///
 | ||||
|     /// When accessing `x` or `y` out of bounds.
 | ||||
|     fn set(&mut self, x: usize, y: usize, value: T) -> T; | ||||
|     fn set(&mut self, x: usize, y: usize, value: T); | ||||
| 
 | ||||
|     /// Get the current value at the specified position
 | ||||
|     ///
 | ||||
|  | @ -46,11 +44,12 @@ pub trait Grid<T> { | |||
|     /// * `x` and `y`: position of the cell to read
 | ||||
|     ///
 | ||||
|     /// returns: the old value or None
 | ||||
|     fn set_optional(&mut self, x: isize, y: isize, value: T) -> Option<T> { | ||||
|     fn set_optional(&mut self, x: isize, y: isize, value: T) -> bool { | ||||
|         if self.is_in_bounds(x, y) { | ||||
|             Some(self.set(x as usize, y as usize, value)) | ||||
|             self.set(x as usize, y as usize, value); | ||||
|             true | ||||
|         } else { | ||||
|             None | ||||
|             false | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,7 +2,6 @@ | |||
| 
 | ||||
| use std::time::Duration; | ||||
| 
 | ||||
| pub use crate::bit_vec::BitVec; | ||||
| pub use crate::byte_grid::ByteGrid; | ||||
| pub use crate::command::{Brightness, Command, Offset, Origin}; | ||||
| pub use crate::compression_code::CompressionCode; | ||||
|  | @ -11,8 +10,11 @@ pub use crate::data_ref::DataRef; | |||
| pub use crate::grid::{Grid, RefGrid}; | ||||
| pub use crate::packet::{Header, Packet, Payload}; | ||||
| pub use crate::pixel_grid::PixelGrid; | ||||
| pub use bitvec; | ||||
| use bitvec::prelude::{BitVec, Msb0}; | ||||
| 
 | ||||
| type SpBitVec = BitVec<u8, Msb0>; | ||||
| 
 | ||||
| mod bit_vec; | ||||
| mod byte_grid; | ||||
| mod command; | ||||
| mod command_code; | ||||
|  |  | |||
|  | @ -1,11 +1,14 @@ | |||
| use crate::{BitVec, DataRef, Grid, PIXEL_HEIGHT, PIXEL_WIDTH}; | ||||
| use crate::{BitVec, DataRef, Grid, SpBitVec, PIXEL_HEIGHT, PIXEL_WIDTH}; | ||||
| use bitvec::order::Msb0; | ||||
| use bitvec::prelude::BitSlice; | ||||
| use bitvec::slice::Iter; | ||||
| 
 | ||||
| /// A grid of pixels stored in packed bytes.
 | ||||
| #[derive(Debug, Clone, PartialEq)] | ||||
| pub struct PixelGrid { | ||||
|     width: usize, | ||||
|     height: usize, | ||||
|     bit_vec: BitVec, | ||||
|     bit_vec: SpBitVec, | ||||
| } | ||||
| 
 | ||||
| impl PixelGrid { | ||||
|  | @ -26,7 +29,7 @@ impl PixelGrid { | |||
|         Self { | ||||
|             width, | ||||
|             height, | ||||
|             bit_vec: BitVec::new(width * height), | ||||
|             bit_vec: BitVec::repeat(false, width * height), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -56,11 +59,11 @@ impl PixelGrid { | |||
|         Self { | ||||
|             width, | ||||
|             height, | ||||
|             bit_vec: BitVec::from(data), | ||||
|             bit_vec: BitVec::from_slice(data), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn iter(&self) -> crate::bit_vec::Iter { | ||||
|     pub fn iter(&self) -> Iter<'_, u8, Msb0> { | ||||
|         self.bit_vec.iter() | ||||
|     } | ||||
| 
 | ||||
|  | @ -98,13 +101,13 @@ impl Grid<bool> for PixelGrid { | |||
|     /// # Panics
 | ||||
|     ///
 | ||||
|     /// When accessing `x` or `y` out of bounds.
 | ||||
|     fn set(&mut self, x: usize, y: usize, value: bool) -> bool { | ||||
|     fn set(&mut self, x: usize, y: usize, value: bool) { | ||||
|         self.check_indexes(x, y); | ||||
|         self.bit_vec.set(x + y * self.width, value) | ||||
|     } | ||||
| 
 | ||||
|     fn get(&self, x: usize, y: usize) -> bool { | ||||
|         self.bit_vec.get(x + y * self.width) | ||||
|         self.bit_vec[x + y * self.width] | ||||
|     } | ||||
| 
 | ||||
|     /// Sets the state of all pixels in the `PixelGrid`.
 | ||||
|  | @ -128,11 +131,11 @@ impl Grid<bool> for PixelGrid { | |||
| 
 | ||||
| impl DataRef for PixelGrid { | ||||
|     fn data_ref_mut(&mut self) -> &mut [u8] { | ||||
|         self.bit_vec.data_ref_mut() | ||||
|         self.bit_vec.as_raw_mut_slice() | ||||
|     } | ||||
| 
 | ||||
|     fn data_ref(&self) -> &[u8] { | ||||
|         self.bit_vec.data_ref() | ||||
|         self.bit_vec.as_raw_slice() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -149,19 +152,17 @@ pub struct IterRows<'t> { | |||
| } | ||||
| 
 | ||||
| impl<'t> Iterator for IterRows<'t> { | ||||
|     type Item = crate::bit_vec::Iter<'t>; | ||||
|     type Item = &'t BitSlice<u8, Msb0>; | ||||
| 
 | ||||
|     fn next(&mut self) -> Option<Self::Item> { | ||||
|         if self.row >= self.pixel_grid.height { | ||||
|             return None; | ||||
|         } | ||||
|         let result = Some(crate::bit_vec::Iter { | ||||
|             bit_vec: &self.pixel_grid.bit_vec, | ||||
|             index: self.row * self.pixel_grid.width, | ||||
|             end: (self.row + 1) * self.pixel_grid.width, | ||||
|         }); | ||||
| 
 | ||||
|         let start = self.row * self.pixel_grid.width; | ||||
|         let end = start + self.pixel_grid.width; | ||||
|         self.row += 1; | ||||
|         result | ||||
|         Some(&self.pixel_grid.bit_vec[start..end]) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,9 +2,28 @@ | |||
| //!
 | ||||
| //! prefix `sp_bit_vec_`
 | ||||
| 
 | ||||
| use servicepoint::{BitVec, DataRef}; | ||||
| 
 | ||||
| use crate::c_slice::CByteSlice; | ||||
| use servicepoint::bitvec::prelude::{BitVec, Msb0}; | ||||
| 
 | ||||
| /// cbindgen:no-export
 | ||||
| type SpBitVec = BitVec<u8, Msb0>; | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
| pub struct CBitVec { | ||||
|     actual: SpBitVec, | ||||
| } | ||||
| 
 | ||||
| impl From<SpBitVec> for CBitVec { | ||||
|     fn from(actual: SpBitVec) -> Self { | ||||
|         Self { actual } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<CBitVec> for SpBitVec { | ||||
|     fn from(value: CBitVec) -> Self { | ||||
|         value.actual | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Creates a new `BitVec` instance.
 | ||||
| ///
 | ||||
|  | @ -25,8 +44,10 @@ use crate::c_slice::CByteSlice; | |||
| /// - the returned instance is freed in some way, either by using a consuming function or
 | ||||
| ///   by explicitly calling `sp_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))) | ||||
| pub unsafe extern "C" fn sp_bit_vec_new(size: usize) -> *mut CBitVec { | ||||
|     Box::into_raw(Box::new(CBitVec { | ||||
|         actual: SpBitVec::repeat(false, size), | ||||
|     })) | ||||
| } | ||||
| 
 | ||||
| /// Interpret the data as a series of bits and load then into a new `BitVec` instance.
 | ||||
|  | @ -43,9 +64,11 @@ pub unsafe extern "C" fn sp_bit_vec_new(size: usize) -> *mut BitVec { | |||
| pub unsafe extern "C" fn sp_bit_vec_load( | ||||
|     data: *const u8, | ||||
|     data_length: usize, | ||||
| ) -> *mut BitVec { | ||||
| ) -> *mut CBitVec { | ||||
|     let data = std::slice::from_raw_parts(data, data_length); | ||||
|     Box::into_raw(Box::new(BitVec::from(data))) | ||||
|     Box::into_raw(Box::new(CBitVec { | ||||
|         actual: SpBitVec::from_slice(data), | ||||
|     })) | ||||
| } | ||||
| 
 | ||||
| /// Clones a `BitVec`.
 | ||||
|  | @ -59,7 +82,9 @@ pub unsafe extern "C" fn sp_bit_vec_load( | |||
| /// - the returned instance is freed in some way, either by using a consuming function or
 | ||||
| ///   by explicitly calling `sp_bit_vec_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_clone(this: *const BitVec) -> *mut BitVec { | ||||
| pub unsafe extern "C" fn sp_bit_vec_clone( | ||||
|     this: *const CBitVec, | ||||
| ) -> *mut CBitVec { | ||||
|     Box::into_raw(Box::new((*this).clone())) | ||||
| } | ||||
| 
 | ||||
|  | @ -73,7 +98,7 @@ pub unsafe extern "C" fn sp_bit_vec_clone(this: *const BitVec) -> *mut BitVec { | |||
| /// - `this` is not used concurrently or after this call
 | ||||
| /// - `this` was not passed to another consuming function, e.g. to create a `Command`
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_dealloc(this: *mut BitVec) { | ||||
| pub unsafe extern "C" fn sp_bit_vec_dealloc(this: *mut CBitVec) { | ||||
|     _ = Box::from_raw(this); | ||||
| } | ||||
| 
 | ||||
|  | @ -98,10 +123,10 @@ pub unsafe extern "C" fn sp_bit_vec_dealloc(this: *mut BitVec) { | |||
| /// - `this` is not written to concurrently
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_get( | ||||
|     this: *const BitVec, | ||||
|     this: *const CBitVec, | ||||
|     index: usize, | ||||
| ) -> bool { | ||||
|     (*this).get(index) | ||||
|     *(*this).actual.get(index).unwrap() | ||||
| } | ||||
| 
 | ||||
| /// Sets the value of a bit in the `BitVec`.
 | ||||
|  | @ -126,11 +151,11 @@ pub unsafe extern "C" fn sp_bit_vec_get( | |||
| /// - `this` is not written to or read from concurrently
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_set( | ||||
|     this: *mut BitVec, | ||||
|     this: *mut CBitVec, | ||||
|     index: usize, | ||||
|     value: bool, | ||||
| ) -> bool { | ||||
|     (*this).set(index, value) | ||||
| ) { | ||||
|     (*this).actual.set(index, value) | ||||
| } | ||||
| 
 | ||||
| /// Sets the value of all bits in the `BitVec`.
 | ||||
|  | @ -146,8 +171,8 @@ pub unsafe extern "C" fn sp_bit_vec_set( | |||
| /// - `this` points to a valid `BitVec`
 | ||||
| /// - `this` is not written to or read from concurrently
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_fill(this: *mut BitVec, value: bool) { | ||||
|     (*this).fill(value) | ||||
| pub unsafe extern "C" fn sp_bit_vec_fill(this: *mut CBitVec, value: bool) { | ||||
|     (*this).actual.fill(value) | ||||
| } | ||||
| 
 | ||||
| /// Gets the length of the `BitVec` in bits.
 | ||||
|  | @ -158,8 +183,8 @@ pub unsafe extern "C" fn sp_bit_vec_fill(this: *mut BitVec, value: bool) { | |||
| ///
 | ||||
| /// - `this` points to a valid `BitVec`
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_len(this: *const BitVec) -> usize { | ||||
|     (*this).len() | ||||
| pub unsafe extern "C" fn sp_bit_vec_len(this: *const CBitVec) -> usize { | ||||
|     (*this).actual.len() | ||||
| } | ||||
| 
 | ||||
| /// Returns true if length is 0.
 | ||||
|  | @ -170,8 +195,8 @@ pub unsafe extern "C" fn sp_bit_vec_len(this: *const BitVec) -> usize { | |||
| ///
 | ||||
| /// - `this` points to a valid `BitVec`
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_is_empty(this: *const BitVec) -> bool { | ||||
|     (*this).is_empty() | ||||
| pub unsafe extern "C" fn sp_bit_vec_is_empty(this: *const CBitVec) -> bool { | ||||
|     (*this).actual.is_empty() | ||||
| } | ||||
| 
 | ||||
| /// Gets an unsafe reference to the data of the `BitVec` instance.
 | ||||
|  | @ -185,9 +210,9 @@ pub unsafe extern "C" fn sp_bit_vec_is_empty(this: *const BitVec) -> bool { | |||
| /// - the returned memory range is never accessed concurrently, either via the `BitVec` or directly
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_unsafe_data_ref( | ||||
|     this: *mut BitVec, | ||||
|     this: *mut CBitVec, | ||||
| ) -> CByteSlice { | ||||
|     let data = (*this).data_ref_mut(); | ||||
|     let data = (*this).actual.as_raw_mut_slice(); | ||||
|     CByteSlice { | ||||
|         start: data.as_mut_ptr_range().start, | ||||
|         length: data.len(), | ||||
|  |  | |||
|  | @ -5,10 +5,12 @@ | |||
| use std::ptr::null_mut; | ||||
| 
 | ||||
| use servicepoint::{ | ||||
|     BitVec, Brightness, ByteGrid, Command, CompressionCode, Offset, Origin, | ||||
|     Packet, PixelGrid, | ||||
|     Brightness, ByteGrid, Command, CompressionCode, Offset, Origin, Packet, | ||||
|     PixelGrid, | ||||
| }; | ||||
| 
 | ||||
| use crate::bit_vec::CBitVec; | ||||
| 
 | ||||
| /// Tries to turn a `Packet` into a `Command`. The packet is deallocated in the process.
 | ||||
| ///
 | ||||
| /// Returns: pointer to new `Command` instance or NULL
 | ||||
|  | @ -140,13 +142,13 @@ pub unsafe extern "C" fn sp_command_char_brightness( | |||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_bitmap_linear( | ||||
|     offset: Offset, | ||||
|     bit_vec: *mut BitVec, | ||||
|     bit_vec: *mut CBitVec, | ||||
|     compression: CompressionCode, | ||||
| ) -> *mut Command { | ||||
|     let bit_vec = *Box::from_raw(bit_vec); | ||||
|     Box::into_raw(Box::new(Command::BitmapLinear( | ||||
|         offset, | ||||
|         bit_vec, | ||||
|         bit_vec.into(), | ||||
|         compression, | ||||
|     ))) | ||||
| } | ||||
|  | @ -166,13 +168,13 @@ pub unsafe extern "C" fn sp_command_bitmap_linear( | |||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_bitmap_linear_and( | ||||
|     offset: Offset, | ||||
|     bit_vec: *mut BitVec, | ||||
|     bit_vec: *mut CBitVec, | ||||
|     compression: CompressionCode, | ||||
| ) -> *mut Command { | ||||
|     let bit_vec = *Box::from_raw(bit_vec); | ||||
|     Box::into_raw(Box::new(Command::BitmapLinearAnd( | ||||
|         offset, | ||||
|         bit_vec, | ||||
|         bit_vec.into(), | ||||
|         compression, | ||||
|     ))) | ||||
| } | ||||
|  | @ -192,13 +194,13 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_and( | |||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_bitmap_linear_or( | ||||
|     offset: Offset, | ||||
|     bit_vec: *mut BitVec, | ||||
|     bit_vec: *mut CBitVec, | ||||
|     compression: CompressionCode, | ||||
| ) -> *mut Command { | ||||
|     let bit_vec = *Box::from_raw(bit_vec); | ||||
|     Box::into_raw(Box::new(Command::BitmapLinearOr( | ||||
|         offset, | ||||
|         bit_vec, | ||||
|         bit_vec.into(), | ||||
|         compression, | ||||
|     ))) | ||||
| } | ||||
|  | @ -218,13 +220,13 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_or( | |||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_bitmap_linear_xor( | ||||
|     offset: Offset, | ||||
|     bit_vec: *mut BitVec, | ||||
|     bit_vec: *mut CBitVec, | ||||
|     compression: CompressionCode, | ||||
| ) -> *mut Command { | ||||
|     let bit_vec = *Box::from_raw(bit_vec); | ||||
|     Box::into_raw(Box::new(Command::BitmapLinearXor( | ||||
|         offset, | ||||
|         bit_vec, | ||||
|         bit_vec.into(), | ||||
|         compression, | ||||
|     ))) | ||||
| } | ||||
|  |  | |||
|  | @ -22,4 +22,4 @@ pub mod pixel_grid; | |||
| /// The minimum time needed for the display to refresh the screen in ms.
 | ||||
| pub const FRAME_PACING_MS: u32 = servicepoint::FRAME_PACING.as_millis() as u32; | ||||
| 
 | ||||
| mod c_slice; | ||||
| pub mod c_slice; | ||||
|  |  | |||
|  | @ -21,46 +21,45 @@ namespace ServicePoint.BindGen | |||
| 
 | ||||
|         /// <summary>Creates a new `BitVec` instance.  # Arguments  * `size`: size in bits.  returns: `BitVec` with all bits set to false.  # Panics  When `size` is not divisible by 8.  # Safety  The caller has to make sure that:  - the returned instance is freed in some way, either by using a consuming function or by explicitly calling `sp_bit_vec_dealloc`.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp_bit_vec_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern BitVec* sp_bit_vec_new(nuint size); | ||||
|         public static extern CBitVec* sp_bit_vec_new(nuint size); | ||||
| 
 | ||||
|         /// <summary>Interpret the data as a series of bits and load then into a new `BitVec` instance.  # Safety  The caller has to make sure that:  - `data` points to a valid memory location of at least `data_length` bytes in size. - the returned instance is freed in some way, either by using a consuming function or by explicitly calling `sp_bit_vec_dealloc`.</summary> | ||||
|         [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); | ||||
|         public static extern CBitVec* sp_bit_vec_load(byte* data, nuint data_length); | ||||
| 
 | ||||
|         /// <summary>Clones a `BitVec`.  # Safety  The caller has to make sure that:  - `this` points to a valid `BitVec` - `this` is not written to concurrently - the returned instance is freed in some way, either by using a consuming function or by explicitly calling `sp_bit_vec_dealloc`.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp_bit_vec_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern BitVec* sp_bit_vec_clone(BitVec* @this); | ||||
|         public static extern CBitVec* sp_bit_vec_clone(CBitVec* @this); | ||||
| 
 | ||||
|         /// <summary>Deallocates a `BitVec`.  # Safety  The caller has to make sure that:  - `this` points to a valid `BitVec` - `this` is not used concurrently or after this call - `this` was not passed to another consuming function, e.g. to create a `Command`</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp_bit_vec_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp_bit_vec_dealloc(BitVec* @this); | ||||
|         public static extern void sp_bit_vec_dealloc(CBitVec* @this); | ||||
| 
 | ||||
|         /// <summary>Gets the value of a bit from the `BitVec`.  # Arguments  * `this`: instance to read from * `index`: the bit index to read  returns: value of the bit  # Panics  When accessing `index` out of bounds.  # Safety  The caller has to make sure that:  - `this` points to a valid `BitVec` - `this` is not written to concurrently</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp_bit_vec_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         [return: MarshalAs(UnmanagedType.U1)] | ||||
|         public static extern bool sp_bit_vec_get(BitVec* @this, nuint index); | ||||
|         public static extern bool sp_bit_vec_get(CBitVec* @this, nuint index); | ||||
| 
 | ||||
|         /// <summary>Sets the value of a bit in the `BitVec`.  # Arguments  * `this`: instance to write to * `index`: the bit index to edit * `value`: the value to set the bit to  returns: old value of the bit  # Panics  When accessing `index` out of bounds.  # Safety  The caller has to make sure that:  - `this` points to a valid `BitVec` - `this` is not written to or read from concurrently</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp_bit_vec_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         [return: MarshalAs(UnmanagedType.U1)] | ||||
|         public static extern bool sp_bit_vec_set(BitVec* @this, nuint index, [MarshalAs(UnmanagedType.U1)] bool value); | ||||
|         public static extern void sp_bit_vec_set(CBitVec* @this, nuint index, [MarshalAs(UnmanagedType.U1)] bool value); | ||||
| 
 | ||||
|         /// <summary>Sets the value of all bits in the `BitVec`.  # Arguments  * `value`: the value to set all bits to  # Safety  The caller has to make sure that:  - `this` points to a valid `BitVec` - `this` is not written to or read from concurrently</summary> | ||||
|         [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); | ||||
|         public static extern void sp_bit_vec_fill(CBitVec* @this, [MarshalAs(UnmanagedType.U1)] bool value); | ||||
| 
 | ||||
|         /// <summary>Gets the length of the `BitVec` in bits.  # Safety  The caller has to make sure that:  - `this` points to a valid `BitVec`</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp_bit_vec_len", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern nuint sp_bit_vec_len(BitVec* @this); | ||||
|         public static extern nuint sp_bit_vec_len(CBitVec* @this); | ||||
| 
 | ||||
|         /// <summary>Returns true if length is 0.  # Safety  The caller has to make sure that:  - `this` points to a valid `BitVec`</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp_bit_vec_is_empty", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         [return: MarshalAs(UnmanagedType.U1)] | ||||
|         public static extern bool sp_bit_vec_is_empty(BitVec* @this); | ||||
|         public static extern bool sp_bit_vec_is_empty(CBitVec* @this); | ||||
| 
 | ||||
|         /// <summary>Gets an unsafe reference to the data of the `BitVec` instance.  ## Safety  The caller has to make sure that:  - `this` points to a valid `BitVec` - the returned memory range is never accessed after the passed `BitVec` has been freed - the returned memory range is never accessed concurrently, either via the `BitVec` or directly</summary> | ||||
|         [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); | ||||
|         public static extern CByteSlice sp_bit_vec_unsafe_data_ref(CBitVec* @this); | ||||
| 
 | ||||
|         /// <summary>Creates a new `ByteGrid` with the specified dimensions.  returns: `ByteGrid` initialized to 0.  # Safety  The caller has to make sure that:  - the returned instance is freed in some way, either by using a consuming function or by explicitly calling `sp_byte_grid_dealloc`.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp_byte_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|  | @ -132,19 +131,19 @@ namespace ServicePoint.BindGen | |||
| 
 | ||||
|         /// <summary>Allocates a new `Command::BitmapLinear` instance. The passed `BitVec` gets consumed.  # Safety  The caller has to make sure that:  - `bit_vec` points to a valid instance of `BitVec` - `bit_vec` is not used concurrently or after this call - `compression` matches one of the allowed enum values - the returned `Command` instance is freed in some way, either by using a consuming function or by explicitly calling `sp_command_dealloc`.</summary> | ||||
|         [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); | ||||
|         public static extern Command* sp_command_bitmap_linear(nuint offset, CBitVec* bit_vec, CompressionCode compression); | ||||
| 
 | ||||
|         /// <summary>Allocates a new `Command::BitmapLinearAnd` instance. The passed `BitVec` gets consumed.  # Safety  The caller has to make sure that:  - `bit_vec` points to a valid instance of `BitVec` - `bit_vec` is not used concurrently or after this call - `compression` matches one of the allowed enum values - the returned `Command` instance is freed in some way, either by using a consuming function or by explicitly calling `sp_command_dealloc`.</summary> | ||||
|         [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); | ||||
|         public static extern Command* sp_command_bitmap_linear_and(nuint offset, CBitVec* bit_vec, CompressionCode compression); | ||||
| 
 | ||||
|         /// <summary>Allocates a new `Command::BitmapLinearOr` instance. The passed `BitVec` gets consumed.  # Safety  The caller has to make sure that:  - `bit_vec` points to a valid instance of `BitVec` - `bit_vec` is not used concurrently or after this call - `compression` matches one of the allowed enum values - the returned `Command` instance is freed in some way, either by using a consuming function or by explicitly calling `sp_command_dealloc`.</summary> | ||||
|         [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); | ||||
|         public static extern Command* sp_command_bitmap_linear_or(nuint offset, CBitVec* bit_vec, CompressionCode compression); | ||||
| 
 | ||||
|         /// <summary>Allocates a new `Command::BitmapLinearXor` instance. The passed `BitVec` gets consumed.  # Safety  The caller has to make sure that:  - `bit_vec` points to a valid instance of `BitVec` - `bit_vec` is not used concurrently or after this call - `compression` matches one of the allowed enum values - the returned `Command` instance is freed in some way, either by using a consuming function or by explicitly calling `sp_command_dealloc`.</summary> | ||||
|         [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); | ||||
|         public static extern Command* sp_command_bitmap_linear_xor(nuint offset, CBitVec* bit_vec, CompressionCode compression); | ||||
| 
 | ||||
|         /// <summary>Allocates a new `Command::Cp437Data` instance. The passed `ByteGrid` gets consumed.  # Safety  The caller has to make sure that:  - `byte_grid` points to a valid instance of `ByteGrid` - `byte_grid` is not used concurrently or after this call - the returned `Command` instance is freed in some way, either by using a consuming function or by explicitly calling `sp_command_dealloc`.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp_command_cp437_data", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|  | @ -227,6 +226,11 @@ namespace ServicePoint.BindGen | |||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     [StructLayout(LayoutKind.Sequential)] | ||||
|     public unsafe partial struct CBitVec | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     [StructLayout(LayoutKind.Sequential)] | ||||
|     public unsafe partial struct CByteSlice | ||||
|     { | ||||
|  | @ -234,11 +238,6 @@ namespace ServicePoint.BindGen | |||
|         public nuint length; | ||||
|     } | ||||
| 
 | ||||
|     [StructLayout(LayoutKind.Sequential)] | ||||
|     public unsafe partial struct BitVec | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     [StructLayout(LayoutKind.Sequential)] | ||||
|     public unsafe partial struct ByteGrid | ||||
|     { | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ using ServicePoint.BindGen; | |||
| 
 | ||||
| namespace ServicePoint; | ||||
| 
 | ||||
| public sealed class BitVec : SpNativeInstance<BindGen.BitVec> | ||||
| public sealed class BitVec : SpNativeInstance<BindGen.CBitVec> | ||||
| { | ||||
|     public static BitVec New(int size) | ||||
|     { | ||||
|  | @ -80,7 +80,7 @@ public sealed class BitVec : SpNativeInstance<BindGen.BitVec> | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private unsafe BitVec(BindGen.BitVec* instance) : base(instance) | ||||
|     private unsafe BitVec(BindGen.CBitVec* instance) : base(instance) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -27,19 +27,19 @@ | |||
|     </PropertyGroup> | ||||
| 
 | ||||
|     <!-- generate C# bindings --> | ||||
|     <Target Name="BuildBindings" Condition="'$(Configuration)'=='Release'" BeforeTargets="Build"> | ||||
|     <Target Name="BuildBindings" Condition="'$(Configuration)'=='Release'" BeforeTargets="PrepareForBuild"> | ||||
|         <Exec Command="cargo build --release"/> | ||||
|         <Exec Command="cargo build --manifest-path ../../../crates/servicepoint_binding_c/Cargo.toml --release"/> | ||||
|     </Target> | ||||
|     <Target Name="BuildBindings" Condition="'$(Configuration)'=='Debug'" BeforeTargets="Build"> | ||||
|     <Target Name="BuildBindings" Condition="'$(Configuration)'=='Debug'" BeforeTargets="PrepareForBuild"> | ||||
|         <Exec Command="cargo build"/> | ||||
|         <Exec Command="cargo build --manifest-path ../../../crates/servicepoint_binding_c/Cargo.toml"/> | ||||
|     </Target> | ||||
| 
 | ||||
|     <!-- build native library to include in output --> | ||||
|     <Target Name="BuildLibrary" Condition="'$(Configuration)'=='Release'" BeforeTargets="Build"> | ||||
|         <Exec Command="cargo build --manifest-path ../../../crates/servicepoint/Cargo.toml --release"/> | ||||
|     <Target Name="BuildLibrary" Condition="'$(Configuration)'=='Release'" BeforeTargets="PrepareForBuild"> | ||||
|     </Target> | ||||
|     <Target Name="BuildLibrary" Condition="'$(Configuration)'=='Debug'" BeforeTargets="Build"> | ||||
|         <Exec Command="cargo build --manifest-path ../../../crates/servicepoint/Cargo.toml"/> | ||||
|     <Target Name="BuildLibrary" Condition="'$(Configuration)'=='Debug'" BeforeTargets="PrepareForBuild"> | ||||
|     </Target> | ||||
| 
 | ||||
|     <!-- include native binary in output --> | ||||
|  |  | |||
|  | @ -12,7 +12,6 @@ fn main() { | |||
|         .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/connection.rs") | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vinzenz Schroeter
						Vinzenz Schroeter