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" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" | 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]] | [[package]] | ||||||
| name = "bzip2" | name = "bzip2" | ||||||
| version = "0.4.4" | version = "0.4.4" | ||||||
|  | @ -267,6 +279,12 @@ dependencies = [ | ||||||
|  "miniz_oxide", |  "miniz_oxide", | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "funty" | ||||||
|  | version = "2.0.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "getrandom" | name = "getrandom" | ||||||
| version = "0.2.15" | version = "0.2.15" | ||||||
|  | @ -419,6 +437,12 @@ dependencies = [ | ||||||
|  "proc-macro2", |  "proc-macro2", | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "radium" | ||||||
|  | version = "0.7.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "rand" | name = "rand" | ||||||
| version = "0.8.5" | version = "0.8.5" | ||||||
|  | @ -542,6 +566,7 @@ dependencies = [ | ||||||
| name = "servicepoint" | name = "servicepoint" | ||||||
| version = "0.5.1" | version = "0.5.1" | ||||||
| dependencies = [ | dependencies = [ | ||||||
|  |  "bitvec", | ||||||
|  "bzip2", |  "bzip2", | ||||||
|  "clap 4.5.4", |  "clap 4.5.4", | ||||||
|  "flate2", |  "flate2", | ||||||
|  | @ -602,6 +627,12 @@ dependencies = [ | ||||||
|  "unicode-ident", |  "unicode-ident", | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "tap" | ||||||
|  | version = "1.0.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "tempfile" | name = "tempfile" | ||||||
| version = "3.10.1" | version = "3.10.1" | ||||||
|  | @ -766,6 +797,15 @@ version = "0.52.5" | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" | checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "wyz" | ||||||
|  | version = "0.5.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" | ||||||
|  | dependencies = [ | ||||||
|  |  "tap", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "zstd" | name = "zstd" | ||||||
| version = "0.13.1" | version = "0.13.1" | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ crate-type = ["rlib"] | ||||||
| 
 | 
 | ||||||
| [dependencies] | [dependencies] | ||||||
| log = "0.4" | log = "0.4" | ||||||
|  | bitvec = "1.0" | ||||||
| flate2 = { version = "1.0", optional = true } | flate2 = { version = "1.0", optional = true } | ||||||
| bzip2 = { version = "0.4", optional = true } | bzip2 = { version = "0.4", optional = true } | ||||||
| zstd = { version = "0.13", optional = true } | zstd = { version = "0.13", optional = true } | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ use std::time::Duration; | ||||||
| 
 | 
 | ||||||
| use clap::Parser; | use clap::Parser; | ||||||
| 
 | 
 | ||||||
| use servicepoint::*; | use servicepoint::{bitvec::prelude::BitVec, *}; | ||||||
| 
 | 
 | ||||||
| #[derive(Parser, Debug)] | #[derive(Parser, Debug)] | ||||||
| struct Cli { | struct Cli { | ||||||
|  | @ -34,7 +34,7 @@ fn main() { | ||||||
| 
 | 
 | ||||||
|         // this works because the pixel grid has max size
 |         // this works because the pixel grid has max size
 | ||||||
|         let pixel_data: Vec<u8> = enabled_pixels.clone().into(); |         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 |         connection | ||||||
|             .send(Command::BitmapLinearAnd(0, bit_vec, CompressionCode::Lzma)) |             .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
 |     /// * `x` and `y`: position of the cell
 | ||||||
|     /// * `value`: the value to write to the cell
 |     /// * `value`: the value to write to the cell
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// returns: old value of the cell.
 |  | ||||||
|     ///
 |  | ||||||
|     /// # Panics
 |     /// # Panics
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// When accessing `x` or `y` out of bounds.
 |     /// 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); |         self.check_indexes(x, y); | ||||||
|         let pos = &mut self.data[x + y * self.width]; |         self.data[x + y * self.width] = value; | ||||||
|         let old_val = *pos; |  | ||||||
|         *pos = value; |  | ||||||
|         old_val |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Gets the current value at the specified position.
 |     /// Gets the current value at the specified position.
 | ||||||
|  |  | ||||||
|  | @ -1,7 +1,9 @@ | ||||||
|  | use bitvec::prelude::{BitVec, Msb0}; | ||||||
|  | 
 | ||||||
| use crate::command_code::CommandCode; | use crate::command_code::CommandCode; | ||||||
| use crate::compression::{into_compressed, into_decompressed}; | use crate::compression::{into_compressed, into_decompressed}; | ||||||
| use crate::{ | use crate::{ | ||||||
|     BitVec, ByteGrid, CompressionCode, Grid, Header, Packet, PixelGrid, |     ByteGrid, CompressionCode, Grid, Header, Packet, PixelGrid, SpBitVec, | ||||||
|     TILE_SIZE, |     TILE_SIZE, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -25,6 +27,7 @@ pub type Offset = usize; | ||||||
| /// Type alias for documenting the meaning of the u16 in enum values
 | /// Type alias for documenting the meaning of the u16 in enum values
 | ||||||
| pub type Brightness = u8; | pub type Brightness = u8; | ||||||
| 
 | 
 | ||||||
|  | // TODO: check order
 | ||||||
| /// A command to send to the display.
 | /// A command to send to the display.
 | ||||||
| #[derive(Debug, Clone, PartialEq)] | #[derive(Debug, Clone, PartialEq)] | ||||||
| pub enum Command { | pub enum Command { | ||||||
|  | @ -43,16 +46,16 @@ pub enum Command { | ||||||
|     BitmapLegacy, |     BitmapLegacy, | ||||||
|     /// Set pixel data starting at the offset.
 |     /// Set pixel data starting at the offset.
 | ||||||
|     /// The contained `BitVec` is always uncompressed.
 |     /// 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.
 |     /// Set pixel data according to an and-mask starting at the offset.
 | ||||||
|     /// The contained `BitVec` is always uncompressed.
 |     /// 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.
 |     /// Set pixel data according to an or-mask starting at the offset.
 | ||||||
|     /// The contained `BitVec` is always uncompressed.
 |     /// 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.
 |     /// Set pixel data according to a xor-mask starting at the offset.
 | ||||||
|     /// The contained `BitVec` is always uncompressed.
 |     /// 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.
 |     /// Show text on the screen. Note that the byte data has to be CP437 encoded.
 | ||||||
|     Cp437Data(Origin, ByteGrid), |     Cp437Data(Origin, ByteGrid), | ||||||
|     /// Sets a window of pixels to the specified values
 |     /// Sets a window of pixels to the specified values
 | ||||||
|  | @ -366,7 +369,7 @@ impl Command { | ||||||
|     /// Helper method for Packets into `BitMapLinear*`-Commands
 |     /// Helper method for Packets into `BitMapLinear*`-Commands
 | ||||||
|     fn packet_into_linear_bitmap( |     fn packet_into_linear_bitmap( | ||||||
|         packet: Packet, |         packet: Packet, | ||||||
|     ) -> Result<(BitVec, CompressionCode), TryFromPacketError> { |     ) -> Result<(BitVec<u8, Msb0>, CompressionCode), TryFromPacketError> { | ||||||
|         let Packet(Header(_, _, length, sub, reserved), payload) = packet; |         let Packet(Header(_, _, length, sub, reserved), payload) = packet; | ||||||
|         if reserved != 0 { |         if reserved != 0 { | ||||||
|             return Err(TryFromPacketError::ExtraneousHeaderValues); |             return Err(TryFromPacketError::ExtraneousHeaderValues); | ||||||
|  | @ -387,17 +390,18 @@ impl Command { | ||||||
|                 payload.len(), |                 payload.len(), | ||||||
|             )); |             )); | ||||||
|         } |         } | ||||||
|         Ok((BitVec::from(&*payload), sub)) |         Ok((BitVec::from_vec(payload), sub)) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[cfg(test)] | #[cfg(test)] | ||||||
| mod tests { | mod tests { | ||||||
|  |     use bitvec::prelude::BitVec; | ||||||
|  | 
 | ||||||
|     use crate::command::TryFromPacketError; |     use crate::command::TryFromPacketError; | ||||||
|     use crate::command_code::CommandCode; |     use crate::command_code::CommandCode; | ||||||
|     use crate::{ |     use crate::{ | ||||||
|         BitVec, ByteGrid, Command, CompressionCode, Grid, Header, Origin, |         ByteGrid, Command, CompressionCode, Header, Origin, Packet, PixelGrid, | ||||||
|         Packet, PixelGrid, |  | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     fn round_trip(original: Command) { |     fn round_trip(original: Command) { | ||||||
|  | @ -462,20 +466,24 @@ mod tests { | ||||||
|     #[test] |     #[test] | ||||||
|     fn round_trip_bitmap_linear() { |     fn round_trip_bitmap_linear() { | ||||||
|         for compression in all_compressions().to_owned() { |         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( |             round_trip(Command::BitmapLinearAnd( | ||||||
|                 23, |                 23, | ||||||
|                 BitVec::new(40), |                 BitVec::repeat(false, 40), | ||||||
|                 compression, |                 compression, | ||||||
|             )); |             )); | ||||||
|             round_trip(Command::BitmapLinearOr( |             round_trip(Command::BitmapLinearOr( | ||||||
|                 23, |                 23, | ||||||
|                 BitVec::new(40), |                 BitVec::repeat(false, 40), | ||||||
|                 compression, |                 compression, | ||||||
|             )); |             )); | ||||||
|             round_trip(Command::BitmapLinearXor( |             round_trip(Command::BitmapLinearXor( | ||||||
|                 23, |                 23, | ||||||
|                 BitVec::new(40), |                 BitVec::repeat(false, 40), | ||||||
|                 compression, |                 compression, | ||||||
|             )); |             )); | ||||||
|             round_trip(Command::BitmapLinearWin( |             round_trip(Command::BitmapLinearWin( | ||||||
|  | @ -590,8 +598,12 @@ mod tests { | ||||||
|     #[test] |     #[test] | ||||||
|     fn error_decompression_failed_and() { |     fn error_decompression_failed_and() { | ||||||
|         for compression in all_compressions().to_owned() { |         for compression in all_compressions().to_owned() { | ||||||
|             let p: Packet = |             let p: Packet = Command::BitmapLinearAnd( | ||||||
|                 Command::BitmapLinearAnd(0, BitVec::new(8), compression).into(); |                 0, | ||||||
|  |                 BitVec::repeat(false, 8), | ||||||
|  |                 compression, | ||||||
|  |             ) | ||||||
|  |             .into(); | ||||||
|             let Packet(header, mut payload) = p; |             let Packet(header, mut payload) = p; | ||||||
| 
 | 
 | ||||||
|             // mangle it
 |             // mangle it
 | ||||||
|  | @ -633,7 +645,7 @@ mod tests { | ||||||
|     fn error_reserved_used() { |     fn error_reserved_used() { | ||||||
|         let Packet(header, payload) = Command::BitmapLinear( |         let Packet(header, payload) = Command::BitmapLinear( | ||||||
|             0, |             0, | ||||||
|             BitVec::new(8), |             BitVec::repeat(false, 8), | ||||||
|             CompressionCode::Uncompressed, |             CompressionCode::Uncompressed, | ||||||
|         ) |         ) | ||||||
|         .into(); |         .into(); | ||||||
|  | @ -649,7 +661,7 @@ mod tests { | ||||||
|     fn error_invalid_compression() { |     fn error_invalid_compression() { | ||||||
|         let Packet(header, payload) = Command::BitmapLinear( |         let Packet(header, payload) = Command::BitmapLinear( | ||||||
|             0, |             0, | ||||||
|             BitVec::new(8), |             BitVec::repeat(false, 8), | ||||||
|             CompressionCode::Uncompressed, |             CompressionCode::Uncompressed, | ||||||
|         ) |         ) | ||||||
|         .into(); |         .into(); | ||||||
|  | @ -665,7 +677,7 @@ mod tests { | ||||||
|     fn error_unexpected_size() { |     fn error_unexpected_size() { | ||||||
|         let Packet(header, payload) = Command::BitmapLinear( |         let Packet(header, payload) = Command::BitmapLinear( | ||||||
|             0, |             0, | ||||||
|             BitVec::new(8), |             BitVec::repeat(false, 8), | ||||||
|             CompressionCode::Uncompressed, |             CompressionCode::Uncompressed, | ||||||
|         ) |         ) | ||||||
|         .into(); |         .into(); | ||||||
|  |  | ||||||
|  | @ -6,12 +6,10 @@ pub trait Grid<T> { | ||||||
|     ///
 |     ///
 | ||||||
|     /// * `x` and `y`: position of the cell to read
 |     /// * `x` and `y`: position of the cell to read
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// returns: the old value
 |  | ||||||
|     ///
 |  | ||||||
|     /// # Panics
 |     /// # Panics
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// When accessing `x` or `y` out of bounds.
 |     /// 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
 |     /// 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
 |     /// * `x` and `y`: position of the cell to read
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// returns: the old value or None
 |     /// 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) { |         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 { |         } else { | ||||||
|             None |             false | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ | ||||||
| 
 | 
 | ||||||
| use std::time::Duration; | use std::time::Duration; | ||||||
| 
 | 
 | ||||||
| pub use crate::bit_vec::BitVec; |  | ||||||
| pub use crate::byte_grid::ByteGrid; | pub use crate::byte_grid::ByteGrid; | ||||||
| pub use crate::command::{Brightness, Command, Offset, Origin}; | pub use crate::command::{Brightness, Command, Offset, Origin}; | ||||||
| pub use crate::compression_code::CompressionCode; | 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::grid::{Grid, RefGrid}; | ||||||
| pub use crate::packet::{Header, Packet, Payload}; | pub use crate::packet::{Header, Packet, Payload}; | ||||||
| pub use crate::pixel_grid::PixelGrid; | 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 byte_grid; | ||||||
| mod command; | mod command; | ||||||
| mod command_code; | 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.
 | /// A grid of pixels stored in packed bytes.
 | ||||||
| #[derive(Debug, Clone, PartialEq)] | #[derive(Debug, Clone, PartialEq)] | ||||||
| pub struct PixelGrid { | pub struct PixelGrid { | ||||||
|     width: usize, |     width: usize, | ||||||
|     height: usize, |     height: usize, | ||||||
|     bit_vec: BitVec, |     bit_vec: SpBitVec, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl PixelGrid { | impl PixelGrid { | ||||||
|  | @ -26,7 +29,7 @@ impl PixelGrid { | ||||||
|         Self { |         Self { | ||||||
|             width, |             width, | ||||||
|             height, |             height, | ||||||
|             bit_vec: BitVec::new(width * height), |             bit_vec: BitVec::repeat(false, width * height), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -56,11 +59,11 @@ impl PixelGrid { | ||||||
|         Self { |         Self { | ||||||
|             width, |             width, | ||||||
|             height, |             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() |         self.bit_vec.iter() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -98,13 +101,13 @@ impl Grid<bool> for PixelGrid { | ||||||
|     /// # Panics
 |     /// # Panics
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// When accessing `x` or `y` out of bounds.
 |     /// 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.check_indexes(x, y); | ||||||
|         self.bit_vec.set(x + y * self.width, value) |         self.bit_vec.set(x + y * self.width, value) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn get(&self, x: usize, y: usize) -> bool { |     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`.
 |     /// Sets the state of all pixels in the `PixelGrid`.
 | ||||||
|  | @ -128,11 +131,11 @@ impl Grid<bool> for PixelGrid { | ||||||
| 
 | 
 | ||||||
| impl DataRef for PixelGrid { | impl DataRef for PixelGrid { | ||||||
|     fn data_ref_mut(&mut self) -> &mut [u8] { |     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] { |     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> { | 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> { |     fn next(&mut self) -> Option<Self::Item> { | ||||||
|         if self.row >= self.pixel_grid.height { |         if self.row >= self.pixel_grid.height { | ||||||
|             return None; |             return None; | ||||||
|         } |         } | ||||||
|         let result = Some(crate::bit_vec::Iter { | 
 | ||||||
|             bit_vec: &self.pixel_grid.bit_vec, |         let start = self.row * self.pixel_grid.width; | ||||||
|             index: self.row * self.pixel_grid.width, |         let end = start + self.pixel_grid.width; | ||||||
|             end: (self.row + 1) * self.pixel_grid.width, |  | ||||||
|         }); |  | ||||||
|         self.row += 1; |         self.row += 1; | ||||||
|         result |         Some(&self.pixel_grid.bit_vec[start..end]) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2,9 +2,28 @@ | ||||||
| //!
 | //!
 | ||||||
| //! prefix `sp_bit_vec_`
 | //! prefix `sp_bit_vec_`
 | ||||||
| 
 | 
 | ||||||
| use servicepoint::{BitVec, DataRef}; |  | ||||||
| 
 |  | ||||||
| use crate::c_slice::CByteSlice; | 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.
 | /// 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
 | /// - the returned instance is freed in some way, either by using a consuming function or
 | ||||||
| ///   by explicitly calling `sp_bit_vec_dealloc`.
 | ///   by explicitly calling `sp_bit_vec_dealloc`.
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bit_vec_new(size: usize) -> *mut BitVec { | pub unsafe extern "C" fn sp_bit_vec_new(size: usize) -> *mut CBitVec { | ||||||
|     Box::into_raw(Box::new(BitVec::new(size))) |     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.
 | /// 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( | pub unsafe extern "C" fn sp_bit_vec_load( | ||||||
|     data: *const u8, |     data: *const u8, | ||||||
|     data_length: usize, |     data_length: usize, | ||||||
| ) -> *mut BitVec { | ) -> *mut CBitVec { | ||||||
|     let data = std::slice::from_raw_parts(data, data_length); |     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`.
 | /// 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
 | /// - the returned instance is freed in some way, either by using a consuming function or
 | ||||||
| ///   by explicitly calling `sp_bit_vec_dealloc`.
 | ///   by explicitly calling `sp_bit_vec_dealloc`.
 | ||||||
| #[no_mangle] | #[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())) |     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` is not used concurrently or after this call
 | ||||||
| /// - `this` was not passed to another consuming function, e.g. to create a `Command`
 | /// - `this` was not passed to another consuming function, e.g. to create a `Command`
 | ||||||
| #[no_mangle] | #[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); |     _ = 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
 | /// - `this` is not written to concurrently
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bit_vec_get( | pub unsafe extern "C" fn sp_bit_vec_get( | ||||||
|     this: *const BitVec, |     this: *const CBitVec, | ||||||
|     index: usize, |     index: usize, | ||||||
| ) -> bool { | ) -> bool { | ||||||
|     (*this).get(index) |     *(*this).actual.get(index).unwrap() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Sets the value of a bit in the `BitVec`.
 | /// 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
 | /// - `this` is not written to or read from concurrently
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bit_vec_set( | pub unsafe extern "C" fn sp_bit_vec_set( | ||||||
|     this: *mut BitVec, |     this: *mut CBitVec, | ||||||
|     index: usize, |     index: usize, | ||||||
|     value: bool, |     value: bool, | ||||||
| ) -> bool { | ) { | ||||||
|     (*this).set(index, value) |     (*this).actual.set(index, value) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Sets the value of all bits in the `BitVec`.
 | /// 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` points to a valid `BitVec`
 | ||||||
| /// - `this` is not written to or read from concurrently
 | /// - `this` is not written to or read from concurrently
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bit_vec_fill(this: *mut BitVec, value: bool) { | pub unsafe extern "C" fn sp_bit_vec_fill(this: *mut CBitVec, value: bool) { | ||||||
|     (*this).fill(value) |     (*this).actual.fill(value) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets the length of the `BitVec` in bits.
 | /// 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`
 | /// - `this` points to a valid `BitVec`
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bit_vec_len(this: *const BitVec) -> usize { | pub unsafe extern "C" fn sp_bit_vec_len(this: *const CBitVec) -> usize { | ||||||
|     (*this).len() |     (*this).actual.len() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Returns true if length is 0.
 | /// 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`
 | /// - `this` points to a valid `BitVec`
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bit_vec_is_empty(this: *const BitVec) -> bool { | pub unsafe extern "C" fn sp_bit_vec_is_empty(this: *const CBitVec) -> bool { | ||||||
|     (*this).is_empty() |     (*this).actual.is_empty() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets an unsafe reference to the data of the `BitVec` instance.
 | /// 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
 | /// - the returned memory range is never accessed concurrently, either via the `BitVec` or directly
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bit_vec_unsafe_data_ref( | pub unsafe extern "C" fn sp_bit_vec_unsafe_data_ref( | ||||||
|     this: *mut BitVec, |     this: *mut CBitVec, | ||||||
| ) -> CByteSlice { | ) -> CByteSlice { | ||||||
|     let data = (*this).data_ref_mut(); |     let data = (*this).actual.as_raw_mut_slice(); | ||||||
|     CByteSlice { |     CByteSlice { | ||||||
|         start: data.as_mut_ptr_range().start, |         start: data.as_mut_ptr_range().start, | ||||||
|         length: data.len(), |         length: data.len(), | ||||||
|  |  | ||||||
|  | @ -5,10 +5,12 @@ | ||||||
| use std::ptr::null_mut; | use std::ptr::null_mut; | ||||||
| 
 | 
 | ||||||
| use servicepoint::{ | use servicepoint::{ | ||||||
|     BitVec, Brightness, ByteGrid, Command, CompressionCode, Offset, Origin, |     Brightness, ByteGrid, Command, CompressionCode, Offset, Origin, Packet, | ||||||
|     Packet, PixelGrid, |     PixelGrid, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | use crate::bit_vec::CBitVec; | ||||||
|  | 
 | ||||||
| /// Tries to turn a `Packet` into a `Command`. The packet is deallocated in the process.
 | /// Tries to turn a `Packet` into a `Command`. The packet is deallocated in the process.
 | ||||||
| ///
 | ///
 | ||||||
| /// Returns: pointer to new `Command` instance or NULL
 | /// Returns: pointer to new `Command` instance or NULL
 | ||||||
|  | @ -140,13 +142,13 @@ pub unsafe extern "C" fn sp_command_char_brightness( | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_command_bitmap_linear( | pub unsafe extern "C" fn sp_command_bitmap_linear( | ||||||
|     offset: Offset, |     offset: Offset, | ||||||
|     bit_vec: *mut BitVec, |     bit_vec: *mut CBitVec, | ||||||
|     compression: CompressionCode, |     compression: CompressionCode, | ||||||
| ) -> *mut Command { | ) -> *mut Command { | ||||||
|     let bit_vec = *Box::from_raw(bit_vec); |     let bit_vec = *Box::from_raw(bit_vec); | ||||||
|     Box::into_raw(Box::new(Command::BitmapLinear( |     Box::into_raw(Box::new(Command::BitmapLinear( | ||||||
|         offset, |         offset, | ||||||
|         bit_vec, |         bit_vec.into(), | ||||||
|         compression, |         compression, | ||||||
|     ))) |     ))) | ||||||
| } | } | ||||||
|  | @ -166,13 +168,13 @@ pub unsafe extern "C" fn sp_command_bitmap_linear( | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_command_bitmap_linear_and( | pub unsafe extern "C" fn sp_command_bitmap_linear_and( | ||||||
|     offset: Offset, |     offset: Offset, | ||||||
|     bit_vec: *mut BitVec, |     bit_vec: *mut CBitVec, | ||||||
|     compression: CompressionCode, |     compression: CompressionCode, | ||||||
| ) -> *mut Command { | ) -> *mut Command { | ||||||
|     let bit_vec = *Box::from_raw(bit_vec); |     let bit_vec = *Box::from_raw(bit_vec); | ||||||
|     Box::into_raw(Box::new(Command::BitmapLinearAnd( |     Box::into_raw(Box::new(Command::BitmapLinearAnd( | ||||||
|         offset, |         offset, | ||||||
|         bit_vec, |         bit_vec.into(), | ||||||
|         compression, |         compression, | ||||||
|     ))) |     ))) | ||||||
| } | } | ||||||
|  | @ -192,13 +194,13 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_and( | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_command_bitmap_linear_or( | pub unsafe extern "C" fn sp_command_bitmap_linear_or( | ||||||
|     offset: Offset, |     offset: Offset, | ||||||
|     bit_vec: *mut BitVec, |     bit_vec: *mut CBitVec, | ||||||
|     compression: CompressionCode, |     compression: CompressionCode, | ||||||
| ) -> *mut Command { | ) -> *mut Command { | ||||||
|     let bit_vec = *Box::from_raw(bit_vec); |     let bit_vec = *Box::from_raw(bit_vec); | ||||||
|     Box::into_raw(Box::new(Command::BitmapLinearOr( |     Box::into_raw(Box::new(Command::BitmapLinearOr( | ||||||
|         offset, |         offset, | ||||||
|         bit_vec, |         bit_vec.into(), | ||||||
|         compression, |         compression, | ||||||
|     ))) |     ))) | ||||||
| } | } | ||||||
|  | @ -218,13 +220,13 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_or( | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_command_bitmap_linear_xor( | pub unsafe extern "C" fn sp_command_bitmap_linear_xor( | ||||||
|     offset: Offset, |     offset: Offset, | ||||||
|     bit_vec: *mut BitVec, |     bit_vec: *mut CBitVec, | ||||||
|     compression: CompressionCode, |     compression: CompressionCode, | ||||||
| ) -> *mut Command { | ) -> *mut Command { | ||||||
|     let bit_vec = *Box::from_raw(bit_vec); |     let bit_vec = *Box::from_raw(bit_vec); | ||||||
|     Box::into_raw(Box::new(Command::BitmapLinearXor( |     Box::into_raw(Box::new(Command::BitmapLinearXor( | ||||||
|         offset, |         offset, | ||||||
|         bit_vec, |         bit_vec.into(), | ||||||
|         compression, |         compression, | ||||||
|     ))) |     ))) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -22,4 +22,4 @@ pub mod pixel_grid; | ||||||
| /// The minimum time needed for the display to refresh the screen in ms.
 | /// 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; | 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> |         /// <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)] |         [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> |         /// <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)] |         [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> |         /// <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)] |         [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> |         /// <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)] |         [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> |         /// <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)] |         [DllImport(__DllName, EntryPoint = "sp_bit_vec_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||||
|         [return: MarshalAs(UnmanagedType.U1)] |         [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> |         /// <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)] |         [DllImport(__DllName, EntryPoint = "sp_bit_vec_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||||
|         [return: MarshalAs(UnmanagedType.U1)] |         public static extern void sp_bit_vec_set(CBitVec* @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); |  | ||||||
| 
 | 
 | ||||||
|         /// <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> |         /// <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)] |         [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> |         /// <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)] |         [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> |         /// <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)] |         [DllImport(__DllName, EntryPoint = "sp_bit_vec_is_empty", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||||
|         [return: MarshalAs(UnmanagedType.U1)] |         [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> |         /// <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)] |         [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> |         /// <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)] |         [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> |         /// <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)] |         [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> |         /// <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)] |         [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> |         /// <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)] |         [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> |         /// <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)] |         [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> |         /// <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)] |         [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)] |     [StructLayout(LayoutKind.Sequential)] | ||||||
|     public unsafe partial struct CByteSlice |     public unsafe partial struct CByteSlice | ||||||
|     { |     { | ||||||
|  | @ -234,11 +238,6 @@ namespace ServicePoint.BindGen | ||||||
|         public nuint length; |         public nuint length; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     [StructLayout(LayoutKind.Sequential)] |  | ||||||
|     public unsafe partial struct BitVec |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     [StructLayout(LayoutKind.Sequential)] |     [StructLayout(LayoutKind.Sequential)] | ||||||
|     public unsafe partial struct ByteGrid |     public unsafe partial struct ByteGrid | ||||||
|     { |     { | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ using ServicePoint.BindGen; | ||||||
| 
 | 
 | ||||||
| namespace ServicePoint; | namespace ServicePoint; | ||||||
| 
 | 
 | ||||||
| public sealed class BitVec : SpNativeInstance<BindGen.BitVec> | public sealed class BitVec : SpNativeInstance<BindGen.CBitVec> | ||||||
| { | { | ||||||
|     public static BitVec New(int size) |     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> |     </PropertyGroup> | ||||||
| 
 | 
 | ||||||
|     <!-- generate C# bindings --> |     <!-- 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 --release"/> | ||||||
|  |         <Exec Command="cargo build --manifest-path ../../../crates/servicepoint_binding_c/Cargo.toml --release"/> | ||||||
|     </Target> |     </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"/> | ||||||
|  |         <Exec Command="cargo build --manifest-path ../../../crates/servicepoint_binding_c/Cargo.toml"/> | ||||||
|     </Target> |     </Target> | ||||||
| 
 | 
 | ||||||
|     <!-- build native library to include in output --> |     <!-- build native library to include in output --> | ||||||
|     <Target Name="BuildLibrary" Condition="'$(Configuration)'=='Release'" BeforeTargets="Build"> |     <Target Name="BuildLibrary" Condition="'$(Configuration)'=='Release'" BeforeTargets="PrepareForBuild"> | ||||||
|         <Exec Command="cargo build --manifest-path ../../../crates/servicepoint/Cargo.toml --release"/> |  | ||||||
|     </Target> |     </Target> | ||||||
|     <Target Name="BuildLibrary" Condition="'$(Configuration)'=='Debug'" BeforeTargets="Build"> |     <Target Name="BuildLibrary" Condition="'$(Configuration)'=='Debug'" BeforeTargets="PrepareForBuild"> | ||||||
|         <Exec Command="cargo build --manifest-path ../../../crates/servicepoint/Cargo.toml"/> |  | ||||||
|     </Target> |     </Target> | ||||||
| 
 | 
 | ||||||
|     <!-- include native binary in output --> |     <!-- 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/lib.rs") | ||||||
|         .input_extern_file("../servicepoint_binding_c/src/c_slice.rs") |         .input_extern_file("../servicepoint_binding_c/src/c_slice.rs") | ||||||
|         .input_extern_file("../servicepoint_binding_c/src/packet.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/byte_grid.rs") | ||||||
|         .input_extern_file("../servicepoint/src/command.rs") |         .input_extern_file("../servicepoint/src/command.rs") | ||||||
|         .input_extern_file("../servicepoint/src/connection.rs") |         .input_extern_file("../servicepoint/src/connection.rs") | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vinzenz Schroeter
						Vinzenz Schroeter