add /*notnull*/ comments in header, use NotNull for parameters
This commit is contained in:
		
							parent
							
								
									bb90af3a57
								
							
						
					
					
						commit
						40fed5ba04
					
				
					 13 changed files with 299 additions and 385 deletions
				
			
		
							
								
								
									
										4
									
								
								build.rs
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								build.rs
									
										
									
									
									
								
							|  | @ -10,7 +10,9 @@ fn main() { | ||||||
|     let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); |     let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); | ||||||
|     println!("cargo::rerun-if-changed={crate_dir}"); |     println!("cargo::rerun-if-changed={crate_dir}"); | ||||||
| 
 | 
 | ||||||
|     let config = cbindgen::Config::from_file(crate_dir.clone() + "/cbindgen.toml").unwrap(); |     let config = | ||||||
|  |         cbindgen::Config::from_file(crate_dir.clone() + "/cbindgen.toml") | ||||||
|  |             .unwrap(); | ||||||
| 
 | 
 | ||||||
|     let output_dir = env::var("OUT_DIR").unwrap(); |     let output_dir = env::var("OUT_DIR").unwrap(); | ||||||
|     let header_file = output_dir.clone() + "/servicepoint.h"; |     let header_file = output_dir.clone() + "/servicepoint.h"; | ||||||
|  |  | ||||||
|  | @ -39,3 +39,6 @@ exclude = [] | ||||||
| 
 | 
 | ||||||
| [enum] | [enum] | ||||||
| rename_variants = "QualifiedScreamingSnakeCase" | rename_variants = "QualifiedScreamingSnakeCase" | ||||||
|  | 
 | ||||||
|  | [ptr] | ||||||
|  | non_null_attribute = "/*notnull*/" | ||||||
|  |  | ||||||
|  | @ -239,7 +239,7 @@ typedef struct { | ||||||
|     /**
 |     /**
 | ||||||
|      * The start address of the memory |      * The start address of the memory | ||||||
|      */ |      */ | ||||||
|     uint8_t *start; |     uint8_t */*notnull*/ start; | ||||||
|     /**
 |     /**
 | ||||||
|      * The amount of memory in bytes |      * The amount of memory in bytes | ||||||
|      */ |      */ | ||||||
|  | @ -351,7 +351,7 @@ extern "C" { | ||||||
|  * - 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_bitmap_free`. |  *   by explicitly calling `sp_bitmap_free`. | ||||||
|  */ |  */ | ||||||
| Bitmap *sp_bitmap_clone(const Bitmap *bitmap); | Bitmap */*notnull*/ sp_bitmap_clone(Bitmap */*notnull*/ bitmap); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Sets the state of all pixels in the [SPBitmap]. |  * Sets the state of all pixels in the [SPBitmap]. | ||||||
|  | @ -372,7 +372,7 @@ Bitmap *sp_bitmap_clone(const Bitmap *bitmap); | ||||||
|  * - `bitmap` points to a valid [SPBitmap] |  * - `bitmap` points to a valid [SPBitmap] | ||||||
|  * - `bitmap` is not written to or read from concurrently |  * - `bitmap` is not written to or read from concurrently | ||||||
|  */ |  */ | ||||||
| void sp_bitmap_fill(Bitmap *bitmap, bool value); | void sp_bitmap_fill(Bitmap */*notnull*/ bitmap, bool value); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Deallocates a [SPBitmap]. |  * Deallocates a [SPBitmap]. | ||||||
|  | @ -386,12 +386,10 @@ void sp_bitmap_fill(Bitmap *bitmap, bool value); | ||||||
|  * The caller has to make sure that: |  * The caller has to make sure that: | ||||||
|  * |  * | ||||||
|  * - `bitmap` points to a valid [SPBitmap] |  * - `bitmap` points to a valid [SPBitmap] | ||||||
|  * - `bitmap` is not used concurrently or after bitmap call |  | ||||||
|  * - `bitmap` was not passed to another consuming function, e.g. to create a [SPCommand] |  | ||||||
|  * |  * | ||||||
|  * [SPCommand]: [crate::SPCommand] |  * [SPCommand]: [crate::SPCommand] | ||||||
|  */ |  */ | ||||||
| void sp_bitmap_free(Bitmap *bitmap); | void sp_bitmap_free(Bitmap */*notnull*/ bitmap); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Gets the current value at the specified position in the [SPBitmap]. |  * Gets the current value at the specified position in the [SPBitmap]. | ||||||
|  | @ -413,7 +411,7 @@ void sp_bitmap_free(Bitmap *bitmap); | ||||||
|  * - `bitmap` points to a valid [SPBitmap] |  * - `bitmap` points to a valid [SPBitmap] | ||||||
|  * - `bitmap` is not written to concurrently |  * - `bitmap` is not written to concurrently | ||||||
|  */ |  */ | ||||||
| bool sp_bitmap_get(const Bitmap *bitmap, size_t x, size_t y); | bool sp_bitmap_get(Bitmap */*notnull*/ bitmap, size_t x, size_t y); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Gets the height in pixels of the [SPBitmap] instance. |  * Gets the height in pixels of the [SPBitmap] instance. | ||||||
|  | @ -432,7 +430,7 @@ bool sp_bitmap_get(const Bitmap *bitmap, size_t x, size_t y); | ||||||
|  * |  * | ||||||
|  * - `bitmap` points to a valid [SPBitmap] |  * - `bitmap` points to a valid [SPBitmap] | ||||||
|  */ |  */ | ||||||
| size_t sp_bitmap_height(const Bitmap *bitmap); | size_t sp_bitmap_height(Bitmap */*notnull*/ bitmap); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Loads a [SPBitmap] with the specified dimensions from the provided data. |  * Loads a [SPBitmap] with the specified dimensions from the provided data. | ||||||
|  | @ -465,8 +463,7 @@ size_t sp_bitmap_height(const Bitmap *bitmap); | ||||||
|  */ |  */ | ||||||
| Bitmap *sp_bitmap_load(size_t width, | Bitmap *sp_bitmap_load(size_t width, | ||||||
|                        size_t height, |                        size_t height, | ||||||
|                        const uint8_t *data, |                        SPByteSlice data); | ||||||
|                        size_t data_length); |  | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Creates a new [SPBitmap] with the specified dimensions. |  * Creates a new [SPBitmap] with the specified dimensions. | ||||||
|  | @ -506,7 +503,7 @@ Bitmap *sp_bitmap_new(size_t width, | ||||||
|  * - 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_bitmap_free]. |  *   by explicitly calling [sp_bitmap_free]. | ||||||
|  */ |  */ | ||||||
| Bitmap *sp_bitmap_new_screen_sized(void); | Bitmap */*notnull*/ sp_bitmap_new_screen_sized(void); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Sets the value of the specified position in the [SPBitmap]. |  * Sets the value of the specified position in the [SPBitmap]. | ||||||
|  | @ -531,7 +528,7 @@ Bitmap *sp_bitmap_new_screen_sized(void); | ||||||
|  * - `bitmap` points to a valid [SPBitmap] |  * - `bitmap` points to a valid [SPBitmap] | ||||||
|  * - `bitmap` is not written to or read from concurrently |  * - `bitmap` is not written to or read from concurrently | ||||||
|  */ |  */ | ||||||
| void sp_bitmap_set(Bitmap *bitmap, size_t x, size_t y, bool value); | void sp_bitmap_set(Bitmap */*notnull*/ bitmap, size_t x, size_t y, bool value); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Gets an unsafe reference to the data of the [SPBitmap] instance. |  * Gets an unsafe reference to the data of the [SPBitmap] instance. | ||||||
|  | @ -548,7 +545,7 @@ void sp_bitmap_set(Bitmap *bitmap, size_t x, size_t y, bool value); | ||||||
|  * - the returned memory range is never accessed after the passed [SPBitmap] has been freed |  * - the returned memory range is never accessed after the passed [SPBitmap] has been freed | ||||||
|  * - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly |  * - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly | ||||||
|  */ |  */ | ||||||
| SPByteSlice sp_bitmap_unsafe_data_ref(Bitmap *bitmap); | SPByteSlice sp_bitmap_unsafe_data_ref(Bitmap */*notnull*/ bitmap); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Gets the width in pixels of the [SPBitmap] instance. |  * Gets the width in pixels of the [SPBitmap] instance. | ||||||
|  | @ -567,7 +564,7 @@ SPByteSlice sp_bitmap_unsafe_data_ref(Bitmap *bitmap); | ||||||
|  * |  * | ||||||
|  * - `bitmap` points to a valid [SPBitmap] |  * - `bitmap` points to a valid [SPBitmap] | ||||||
|  */ |  */ | ||||||
| size_t sp_bitmap_width(const Bitmap *bitmap); | size_t sp_bitmap_width(Bitmap */*notnull*/ bitmap); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Clones a [SPBitVec]. |  * Clones a [SPBitVec]. | ||||||
|  | @ -587,7 +584,7 @@ size_t sp_bitmap_width(const Bitmap *bitmap); | ||||||
|  * - 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_bitvec_free`. |  *   by explicitly calling `sp_bitvec_free`. | ||||||
|  */ |  */ | ||||||
| SPBitVec *sp_bitvec_clone(const SPBitVec *bit_vec); | SPBitVec */*notnull*/ sp_bitvec_clone(SPBitVec */*notnull*/ bit_vec); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Sets the value of all bits in the [SPBitVec]. |  * Sets the value of all bits in the [SPBitVec]. | ||||||
|  | @ -608,7 +605,7 @@ SPBitVec *sp_bitvec_clone(const SPBitVec *bit_vec); | ||||||
|  * - `bit_vec` points to a valid [SPBitVec] |  * - `bit_vec` points to a valid [SPBitVec] | ||||||
|  * - `bit_vec` is not written to or read from concurrently |  * - `bit_vec` is not written to or read from concurrently | ||||||
|  */ |  */ | ||||||
| void sp_bitvec_fill(SPBitVec *bit_vec, bool value); | void sp_bitvec_fill(SPBitVec */*notnull*/ bit_vec, bool value); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Deallocates a [SPBitVec]. |  * Deallocates a [SPBitVec]. | ||||||
|  | @ -627,7 +624,7 @@ void sp_bitvec_fill(SPBitVec *bit_vec, bool value); | ||||||
|  * |  * | ||||||
|  * [SPCommand]: [crate::SPCommand] |  * [SPCommand]: [crate::SPCommand] | ||||||
|  */ |  */ | ||||||
| void sp_bitvec_free(SPBitVec *bit_vec); | void sp_bitvec_free(SPBitVec */*notnull*/ bit_vec); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Gets the value of a bit from the [SPBitVec]. |  * Gets the value of a bit from the [SPBitVec]. | ||||||
|  | @ -651,7 +648,7 @@ void sp_bitvec_free(SPBitVec *bit_vec); | ||||||
|  * - `bit_vec` points to a valid [SPBitVec] |  * - `bit_vec` points to a valid [SPBitVec] | ||||||
|  * - `bit_vec` is not written to concurrently |  * - `bit_vec` is not written to concurrently | ||||||
|  */ |  */ | ||||||
| bool sp_bitvec_get(const SPBitVec *bit_vec, size_t index); | bool sp_bitvec_get(SPBitVec */*notnull*/ bit_vec, size_t index); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Returns true if length is 0. |  * Returns true if length is 0. | ||||||
|  | @ -670,7 +667,7 @@ bool sp_bitvec_get(const SPBitVec *bit_vec, size_t index); | ||||||
|  * |  * | ||||||
|  * - `bit_vec` points to a valid [SPBitVec] |  * - `bit_vec` points to a valid [SPBitVec] | ||||||
|  */ |  */ | ||||||
| bool sp_bitvec_is_empty(const SPBitVec *bit_vec); | bool sp_bitvec_is_empty(SPBitVec */*notnull*/ bit_vec); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Gets the length of the [SPBitVec] in bits. |  * Gets the length of the [SPBitVec] in bits. | ||||||
|  | @ -689,7 +686,7 @@ bool sp_bitvec_is_empty(const SPBitVec *bit_vec); | ||||||
|  * |  * | ||||||
|  * - `bit_vec` points to a valid [SPBitVec] |  * - `bit_vec` points to a valid [SPBitVec] | ||||||
|  */ |  */ | ||||||
| size_t sp_bitvec_len(const SPBitVec *bit_vec); | size_t sp_bitvec_len(SPBitVec */*notnull*/ bit_vec); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Interpret the data as a series of bits and load then into a new [SPBitVec] instance. |  * Interpret the data as a series of bits and load then into a new [SPBitVec] instance. | ||||||
|  | @ -709,8 +706,7 @@ size_t sp_bitvec_len(const SPBitVec *bit_vec); | ||||||
|  * - 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_bitvec_free`. |  *   by explicitly calling `sp_bitvec_free`. | ||||||
|  */ |  */ | ||||||
| SPBitVec *sp_bitvec_load(const uint8_t *data, | SPBitVec */*notnull*/ sp_bitvec_load(SPByteSlice data); | ||||||
|                          size_t data_length); |  | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Creates a new [SPBitVec] instance. |  * Creates a new [SPBitVec] instance. | ||||||
|  | @ -732,7 +728,7 @@ SPBitVec *sp_bitvec_load(const uint8_t *data, | ||||||
|  * - 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_bitvec_free`. |  *   by explicitly calling `sp_bitvec_free`. | ||||||
|  */ |  */ | ||||||
| SPBitVec *sp_bitvec_new(size_t size); | SPBitVec */*notnull*/ sp_bitvec_new(size_t size); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Sets the value of a bit in the [SPBitVec]. |  * Sets the value of a bit in the [SPBitVec]. | ||||||
|  | @ -755,7 +751,7 @@ SPBitVec *sp_bitvec_new(size_t size); | ||||||
|  * - `bit_vec` points to a valid [SPBitVec] |  * - `bit_vec` points to a valid [SPBitVec] | ||||||
|  * - `bit_vec` is not written to or read from concurrently |  * - `bit_vec` is not written to or read from concurrently | ||||||
|  */ |  */ | ||||||
| void sp_bitvec_set(SPBitVec *bit_vec, size_t index, bool value); | void sp_bitvec_set(SPBitVec */*notnull*/ bit_vec, size_t index, bool value); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Gets an unsafe reference to the data of the [SPBitVec] instance. |  * Gets an unsafe reference to the data of the [SPBitVec] instance. | ||||||
|  | @ -776,7 +772,7 @@ void sp_bitvec_set(SPBitVec *bit_vec, size_t index, bool value); | ||||||
|  * - the returned memory range is never accessed after the passed [SPBitVec] has been freed |  * - the returned memory range is never accessed after the passed [SPBitVec] has been freed | ||||||
|  * - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly |  * - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly | ||||||
|  */ |  */ | ||||||
| SPByteSlice sp_bitvec_unsafe_data_ref(SPBitVec *bit_vec); | SPByteSlice sp_bitvec_unsafe_data_ref(SPBitVec */*notnull*/ bit_vec); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Clones a [SPBrightnessGrid]. |  * Clones a [SPBrightnessGrid]. | ||||||
|  | @ -800,7 +796,7 @@ SPByteSlice sp_bitvec_unsafe_data_ref(SPBitVec *bit_vec); | ||||||
|  * - 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_brightness_grid_free`. |  *   by explicitly calling `sp_brightness_grid_free`. | ||||||
|  */ |  */ | ||||||
| BrightnessGrid *sp_brightness_grid_clone(const BrightnessGrid *brightness_grid); | BrightnessGrid */*notnull*/ sp_brightness_grid_clone(BrightnessGrid */*notnull*/ brightness_grid); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Sets the value of all cells in the [SPBrightnessGrid]. |  * Sets the value of all cells in the [SPBrightnessGrid]. | ||||||
|  | @ -822,7 +818,8 @@ BrightnessGrid *sp_brightness_grid_clone(const BrightnessGrid *brightness_grid); | ||||||
|  * - `brightness_grid` points to a valid [SPBrightnessGrid] |  * - `brightness_grid` points to a valid [SPBrightnessGrid] | ||||||
|  * - `brightness_grid` is not written to or read from concurrently |  * - `brightness_grid` is not written to or read from concurrently | ||||||
|  */ |  */ | ||||||
| void sp_brightness_grid_fill(BrightnessGrid *brightness_grid, uint8_t value); | void sp_brightness_grid_fill(BrightnessGrid */*notnull*/ brightness_grid, | ||||||
|  |                              uint8_t value); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Deallocates a [SPBrightnessGrid]. |  * Deallocates a [SPBrightnessGrid]. | ||||||
|  | @ -845,7 +842,7 @@ void sp_brightness_grid_fill(BrightnessGrid *brightness_grid, uint8_t value); | ||||||
|  * |  * | ||||||
|  * [SPCommand]: [crate::SPCommand] |  * [SPCommand]: [crate::SPCommand] | ||||||
|  */ |  */ | ||||||
| void sp_brightness_grid_free(BrightnessGrid *brightness_grid); | void sp_brightness_grid_free(BrightnessGrid */*notnull*/ brightness_grid); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Gets the current value at the specified position. |  * Gets the current value at the specified position. | ||||||
|  | @ -869,7 +866,7 @@ void sp_brightness_grid_free(BrightnessGrid *brightness_grid); | ||||||
|  * - `brightness_grid` points to a valid [SPBrightnessGrid] |  * - `brightness_grid` points to a valid [SPBrightnessGrid] | ||||||
|  * - `brightness_grid` is not written to concurrently |  * - `brightness_grid` is not written to concurrently | ||||||
|  */ |  */ | ||||||
| uint8_t sp_brightness_grid_get(const BrightnessGrid *brightness_grid, | uint8_t sp_brightness_grid_get(BrightnessGrid */*notnull*/ brightness_grid, | ||||||
|                                size_t x, |                                size_t x, | ||||||
|                                size_t y); |                                size_t y); | ||||||
| 
 | 
 | ||||||
|  | @ -892,7 +889,7 @@ uint8_t sp_brightness_grid_get(const BrightnessGrid *brightness_grid, | ||||||
|  * |  * | ||||||
|  * - `brightness_grid` points to a valid [SPBrightnessGrid] |  * - `brightness_grid` points to a valid [SPBrightnessGrid] | ||||||
|  */ |  */ | ||||||
| size_t sp_brightness_grid_height(const BrightnessGrid *brightness_grid); | size_t sp_brightness_grid_height(BrightnessGrid */*notnull*/ brightness_grid); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Loads a [SPBrightnessGrid] with the specified dimensions from the provided data. |  * Loads a [SPBrightnessGrid] with the specified dimensions from the provided data. | ||||||
|  | @ -915,8 +912,7 @@ size_t sp_brightness_grid_height(const BrightnessGrid *brightness_grid); | ||||||
|  */ |  */ | ||||||
| BrightnessGrid *sp_brightness_grid_load(size_t width, | BrightnessGrid *sp_brightness_grid_load(size_t width, | ||||||
|                                         size_t height, |                                         size_t height, | ||||||
|                                         const uint8_t *data, |                                         SPByteSlice data); | ||||||
|                                         size_t data_length); |  | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Creates a new [SPBrightnessGrid] with the specified dimensions. |  * Creates a new [SPBrightnessGrid] with the specified dimensions. | ||||||
|  | @ -930,8 +926,8 @@ BrightnessGrid *sp_brightness_grid_load(size_t width, | ||||||
|  * - 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_brightness_grid_free`. |  *   by explicitly calling `sp_brightness_grid_free`. | ||||||
|  */ |  */ | ||||||
| BrightnessGrid *sp_brightness_grid_new(size_t width, | BrightnessGrid */*notnull*/ sp_brightness_grid_new(size_t width, | ||||||
|                                        size_t height); |                                                    size_t height); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Sets the value of the specified position in the [SPBrightnessGrid]. |  * Sets the value of the specified position in the [SPBrightnessGrid]. | ||||||
|  | @ -957,7 +953,7 @@ BrightnessGrid *sp_brightness_grid_new(size_t width, | ||||||
|  * - `brightness_grid` points to a valid [SPBrightnessGrid] |  * - `brightness_grid` points to a valid [SPBrightnessGrid] | ||||||
|  * - `brightness_grid` is not written to or read from concurrently |  * - `brightness_grid` is not written to or read from concurrently | ||||||
|  */ |  */ | ||||||
| void sp_brightness_grid_set(BrightnessGrid *brightness_grid, | void sp_brightness_grid_set(BrightnessGrid */*notnull*/ brightness_grid, | ||||||
|                             size_t x, |                             size_t x, | ||||||
|                             size_t y, |                             size_t y, | ||||||
|                             uint8_t value); |                             uint8_t value); | ||||||
|  | @ -983,7 +979,7 @@ void sp_brightness_grid_set(BrightnessGrid *brightness_grid, | ||||||
|  * - the returned memory range is never accessed after the passed [SPBrightnessGrid] has been freed |  * - the returned memory range is never accessed after the passed [SPBrightnessGrid] has been freed | ||||||
|  * - the returned memory range is never accessed concurrently, either via the [SPBrightnessGrid] or directly |  * - the returned memory range is never accessed concurrently, either via the [SPBrightnessGrid] or directly | ||||||
|  */ |  */ | ||||||
| SPByteSlice sp_brightness_grid_unsafe_data_ref(BrightnessGrid *brightness_grid); | SPByteSlice sp_brightness_grid_unsafe_data_ref(BrightnessGrid */*notnull*/ brightness_grid); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Gets the width of the [SPBrightnessGrid] instance. |  * Gets the width of the [SPBrightnessGrid] instance. | ||||||
|  | @ -1004,7 +1000,7 @@ SPByteSlice sp_brightness_grid_unsafe_data_ref(BrightnessGrid *brightness_grid); | ||||||
|  * |  * | ||||||
|  * - `brightness_grid` points to a valid [SPBrightnessGrid] |  * - `brightness_grid` points to a valid [SPBrightnessGrid] | ||||||
|  */ |  */ | ||||||
| size_t sp_brightness_grid_width(const BrightnessGrid *brightness_grid); | size_t sp_brightness_grid_width(BrightnessGrid */*notnull*/ brightness_grid); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Clones a [SPCharGrid]. |  * Clones a [SPCharGrid]. | ||||||
|  | @ -1024,7 +1020,7 @@ size_t sp_brightness_grid_width(const BrightnessGrid *brightness_grid); | ||||||
|  * - 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_char_grid_free`. |  *   by explicitly calling `sp_char_grid_free`. | ||||||
|  */ |  */ | ||||||
| CharGrid *sp_char_grid_clone(const CharGrid *char_grid); | CharGrid */*notnull*/ sp_char_grid_clone(CharGrid */*notnull*/ char_grid); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Sets the value of all cells in the [SPCharGrid]. |  * Sets the value of all cells in the [SPCharGrid]. | ||||||
|  | @ -1045,7 +1041,7 @@ CharGrid *sp_char_grid_clone(const CharGrid *char_grid); | ||||||
|  * - `char_grid` points to a valid [SPCharGrid] |  * - `char_grid` points to a valid [SPCharGrid] | ||||||
|  * - `char_grid` is not written to or read from concurrently |  * - `char_grid` is not written to or read from concurrently | ||||||
|  */ |  */ | ||||||
| void sp_char_grid_fill(CharGrid *char_grid, uint32_t value); | void sp_char_grid_fill(CharGrid */*notnull*/ char_grid, uint32_t value); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Deallocates a [SPCharGrid]. |  * Deallocates a [SPCharGrid]. | ||||||
|  | @ -1064,7 +1060,7 @@ void sp_char_grid_fill(CharGrid *char_grid, uint32_t value); | ||||||
|  * |  * | ||||||
|  * [SPCommand]: [crate::SPCommand] |  * [SPCommand]: [crate::SPCommand] | ||||||
|  */ |  */ | ||||||
| void sp_char_grid_free(CharGrid *char_grid); | void sp_char_grid_free(CharGrid */*notnull*/ char_grid); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Gets the current value at the specified position. |  * Gets the current value at the specified position. | ||||||
|  | @ -1086,7 +1082,7 @@ void sp_char_grid_free(CharGrid *char_grid); | ||||||
|  * - `char_grid` points to a valid [SPCharGrid] |  * - `char_grid` points to a valid [SPCharGrid] | ||||||
|  * - `char_grid` is not written to concurrently |  * - `char_grid` is not written to concurrently | ||||||
|  */ |  */ | ||||||
| uint32_t sp_char_grid_get(const CharGrid *char_grid, size_t x, size_t y); | uint32_t sp_char_grid_get(CharGrid */*notnull*/ char_grid, size_t x, size_t y); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Gets the height of the [SPCharGrid] instance. |  * Gets the height of the [SPCharGrid] instance. | ||||||
|  | @ -1105,7 +1101,7 @@ uint32_t sp_char_grid_get(const CharGrid *char_grid, size_t x, size_t y); | ||||||
|  * |  * | ||||||
|  * - `char_grid` points to a valid [SPCharGrid] |  * - `char_grid` points to a valid [SPCharGrid] | ||||||
|  */ |  */ | ||||||
| size_t sp_char_grid_height(const CharGrid *char_grid); | size_t sp_char_grid_height(CharGrid */*notnull*/ char_grid); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Loads a [SPCharGrid] with the specified dimensions from the provided data. |  * Loads a [SPCharGrid] with the specified dimensions from the provided data. | ||||||
|  | @ -1127,10 +1123,9 @@ size_t sp_char_grid_height(const CharGrid *char_grid); | ||||||
|  * - 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_char_grid_free`. |  *   by explicitly calling `sp_char_grid_free`. | ||||||
|  */ |  */ | ||||||
| CharGrid *sp_char_grid_load(size_t width, | CharGrid */*notnull*/ sp_char_grid_load(size_t width, | ||||||
|                             size_t height, |                                         size_t height, | ||||||
|                             const uint8_t *data, |                                         SPByteSlice data); | ||||||
|                             size_t data_length); |  | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Creates a new [SPCharGrid] with the specified dimensions. |  * Creates a new [SPCharGrid] with the specified dimensions. | ||||||
|  | @ -1144,8 +1139,8 @@ CharGrid *sp_char_grid_load(size_t width, | ||||||
|  * - 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_char_grid_free`. |  *   by explicitly calling `sp_char_grid_free`. | ||||||
|  */ |  */ | ||||||
| CharGrid *sp_char_grid_new(size_t width, | CharGrid */*notnull*/ sp_char_grid_new(size_t width, | ||||||
|                            size_t height); |                                        size_t height); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Sets the value of the specified position in the [SPCharGrid]. |  * Sets the value of the specified position in the [SPCharGrid]. | ||||||
|  | @ -1172,7 +1167,10 @@ CharGrid *sp_char_grid_new(size_t width, | ||||||
|  * |  * | ||||||
|  * [SPBitVec]: [crate::SPBitVec] |  * [SPBitVec]: [crate::SPBitVec] | ||||||
|  */ |  */ | ||||||
| void sp_char_grid_set(CharGrid *char_grid, size_t x, size_t y, uint32_t value); | void sp_char_grid_set(CharGrid */*notnull*/ char_grid, | ||||||
|  |                       size_t x, | ||||||
|  |                       size_t y, | ||||||
|  |                       uint32_t value); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Gets the width of the [SPCharGrid] instance. |  * Gets the width of the [SPCharGrid] instance. | ||||||
|  | @ -1191,7 +1189,7 @@ void sp_char_grid_set(CharGrid *char_grid, size_t x, size_t y, uint32_t value); | ||||||
|  * |  * | ||||||
|  * - `char_grid` points to a valid [SPCharGrid] |  * - `char_grid` points to a valid [SPCharGrid] | ||||||
|  */ |  */ | ||||||
| size_t sp_char_grid_width(const CharGrid *char_grid); | size_t sp_char_grid_width(CharGrid */*notnull*/ char_grid); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Set pixel data starting at the pixel offset on screen. |  * Set pixel data starting at the pixel offset on screen. | ||||||
|  | @ -1221,7 +1219,7 @@ size_t sp_char_grid_width(const CharGrid *char_grid); | ||||||
|  *   by explicitly calling `sp_command_free`. |  *   by explicitly calling `sp_command_free`. | ||||||
|  */ |  */ | ||||||
| Command *sp_command_bitmap_linear(size_t offset, | Command *sp_command_bitmap_linear(size_t offset, | ||||||
|                                   SPBitVec *bit_vec, |                                   SPBitVec */*notnull*/ bit_vec, | ||||||
|                                   CompressionCode compression); |                                   CompressionCode compression); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | @ -1252,7 +1250,7 @@ Command *sp_command_bitmap_linear(size_t offset, | ||||||
|  *   by explicitly calling `sp_command_free`. |  *   by explicitly calling `sp_command_free`. | ||||||
|  */ |  */ | ||||||
| Command *sp_command_bitmap_linear_and(size_t offset, | Command *sp_command_bitmap_linear_and(size_t offset, | ||||||
|                                       SPBitVec *bit_vec, |                                       SPBitVec */*notnull*/ bit_vec, | ||||||
|                                       CompressionCode compression); |                                       CompressionCode compression); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | @ -1283,7 +1281,7 @@ Command *sp_command_bitmap_linear_and(size_t offset, | ||||||
|  *   by explicitly calling `sp_command_free`. |  *   by explicitly calling `sp_command_free`. | ||||||
|  */ |  */ | ||||||
| Command *sp_command_bitmap_linear_or(size_t offset, | Command *sp_command_bitmap_linear_or(size_t offset, | ||||||
|                                      SPBitVec *bit_vec, |                                      SPBitVec */*notnull*/ bit_vec, | ||||||
|                                      CompressionCode compression); |                                      CompressionCode compression); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | @ -1310,7 +1308,7 @@ Command *sp_command_bitmap_linear_or(size_t offset, | ||||||
|  */ |  */ | ||||||
| Command *sp_command_bitmap_linear_win(size_t x, | Command *sp_command_bitmap_linear_win(size_t x, | ||||||
|                                       size_t y, |                                       size_t y, | ||||||
|                                       Bitmap *bitmap, |                                       Bitmap */*notnull*/ bitmap, | ||||||
|                                       CompressionCode compression); |                                       CompressionCode compression); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | @ -1341,7 +1339,7 @@ Command *sp_command_bitmap_linear_win(size_t x, | ||||||
|  *   by explicitly calling `sp_command_free`. |  *   by explicitly calling `sp_command_free`. | ||||||
|  */ |  */ | ||||||
| Command *sp_command_bitmap_linear_xor(size_t offset, | Command *sp_command_bitmap_linear_xor(size_t offset, | ||||||
|                                       SPBitVec *bit_vec, |                                       SPBitVec */*notnull*/ bit_vec, | ||||||
|                                       CompressionCode compression); |                                       CompressionCode compression); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | @ -1360,7 +1358,7 @@ Command *sp_command_bitmap_linear_xor(size_t offset, | ||||||
|  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or |  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or | ||||||
|  *   by explicitly calling `sp_command_free`. |  *   by explicitly calling `sp_command_free`. | ||||||
|  */ |  */ | ||||||
| Command *sp_command_brightness(uint8_t brightness); | Command */*notnull*/ sp_command_brightness(uint8_t brightness); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Set the brightness of individual tiles in a rectangular area of the display. |  * Set the brightness of individual tiles in a rectangular area of the display. | ||||||
|  | @ -1382,9 +1380,9 @@ Command *sp_command_brightness(uint8_t brightness); | ||||||
|  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or |  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or | ||||||
|  *   by explicitly calling `sp_command_free`. |  *   by explicitly calling `sp_command_free`. | ||||||
|  */ |  */ | ||||||
| Command *sp_command_char_brightness(size_t x, | Command */*notnull*/ sp_command_char_brightness(size_t x, | ||||||
|                                     size_t y, |                                                 size_t y, | ||||||
|                                     BrightnessGrid *grid); |                                                 BrightnessGrid */*notnull*/ grid); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Set all pixels to the off state. |  * Set all pixels to the off state. | ||||||
|  | @ -1406,7 +1404,7 @@ Command *sp_command_char_brightness(size_t x, | ||||||
|  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or |  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or | ||||||
|  *   by explicitly calling `sp_command_free`. |  *   by explicitly calling `sp_command_free`. | ||||||
|  */ |  */ | ||||||
| Command *sp_command_clear(void); | Command */*notnull*/ sp_command_clear(void); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Clones a [SPCommand] instance. |  * Clones a [SPCommand] instance. | ||||||
|  | @ -1426,7 +1424,7 @@ Command *sp_command_clear(void); | ||||||
|  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or |  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or | ||||||
|  *   by explicitly calling `sp_command_free`. |  *   by explicitly calling `sp_command_free`. | ||||||
|  */ |  */ | ||||||
| Command *sp_command_clone(const Command *command); | Command */*notnull*/ sp_command_clone(Command */*notnull*/ command); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Show codepage 437 encoded text on the screen. |  * Show codepage 437 encoded text on the screen. | ||||||
|  | @ -1448,9 +1446,9 @@ Command *sp_command_clone(const Command *command); | ||||||
|  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or |  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or | ||||||
|  *   by explicitly calling `sp_command_free`. |  *   by explicitly calling `sp_command_free`. | ||||||
|  */ |  */ | ||||||
| Command *sp_command_cp437_data(size_t x, | Command */*notnull*/ sp_command_cp437_data(size_t x, | ||||||
|                                size_t y, |                                            size_t y, | ||||||
|                                Cp437Grid *grid); |                                            Cp437Grid */*notnull*/ grid); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * A yet-to-be-tested command. |  * A yet-to-be-tested command. | ||||||
|  | @ -1464,7 +1462,7 @@ Command *sp_command_cp437_data(size_t x, | ||||||
|  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or |  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or | ||||||
|  *   by explicitly calling `sp_command_free`. |  *   by explicitly calling `sp_command_free`. | ||||||
|  */ |  */ | ||||||
| Command *sp_command_fade_out(void); | Command */*notnull*/ sp_command_fade_out(void); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Deallocates a [SPCommand]. |  * Deallocates a [SPCommand]. | ||||||
|  | @ -1488,7 +1486,7 @@ Command *sp_command_fade_out(void); | ||||||
|  * - `command` is not used concurrently or after this call |  * - `command` is not used concurrently or after this call | ||||||
|  * - `command` was not passed to another consuming function, e.g. to create a [SPPacket] |  * - `command` was not passed to another consuming function, e.g. to create a [SPPacket] | ||||||
|  */ |  */ | ||||||
| void sp_command_free(Command *command); | void sp_command_free(Command */*notnull*/ command); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Kills the udp daemon on the display, which usually results in a restart. |  * Kills the udp daemon on the display, which usually results in a restart. | ||||||
|  | @ -1504,7 +1502,7 @@ void sp_command_free(Command *command); | ||||||
|  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or |  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or | ||||||
|  *   by explicitly calling `sp_command_free`. |  *   by explicitly calling `sp_command_free`. | ||||||
|  */ |  */ | ||||||
| Command *sp_command_hard_reset(void); | Command */*notnull*/ sp_command_hard_reset(void); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * A low-level display command. |  * A low-level display command. | ||||||
|  | @ -1541,7 +1539,7 @@ Command *sp_command_hard_reset(void); | ||||||
|  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or |  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or | ||||||
|  *   by explicitly calling `sp_command_free`. |  *   by explicitly calling `sp_command_free`. | ||||||
|  */ |  */ | ||||||
| Command *sp_command_try_from_packet(Packet *packet); | Command *sp_command_try_from_packet(Packet */*notnull*/ packet); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Show UTF-8 encoded text on the screen. |  * Show UTF-8 encoded text on the screen. | ||||||
|  | @ -1563,9 +1561,9 @@ Command *sp_command_try_from_packet(Packet *packet); | ||||||
|  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or |  * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or | ||||||
|  *   by explicitly calling `sp_command_free`. |  *   by explicitly calling `sp_command_free`. | ||||||
|  */ |  */ | ||||||
| Command *sp_command_utf8_data(size_t x, | Command */*notnull*/ sp_command_utf8_data(size_t x, | ||||||
|                               size_t y, |                                           size_t y, | ||||||
|                               CharGrid *grid); |                                           CharGrid */*notnull*/ grid); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Closes and deallocates a [SPConnection]. |  * Closes and deallocates a [SPConnection]. | ||||||
|  | @ -1581,7 +1579,7 @@ Command *sp_command_utf8_data(size_t x, | ||||||
|  * - `connection` points to a valid [SPConnection] |  * - `connection` points to a valid [SPConnection] | ||||||
|  * - `connection` is not used concurrently or after this call |  * - `connection` is not used concurrently or after this call | ||||||
|  */ |  */ | ||||||
| void sp_connection_free(UdpConnection *connection); | void sp_connection_free(UdpConnection */*notnull*/ connection); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Creates a new instance of [SPConnection]. |  * Creates a new instance of [SPConnection]. | ||||||
|  | @ -1599,7 +1597,7 @@ void sp_connection_free(UdpConnection *connection); | ||||||
|  * - 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_connection_free`. |  *   by explicitly calling `sp_connection_free`. | ||||||
|  */ |  */ | ||||||
| UdpConnection *sp_connection_open(const char *host); | UdpConnection *sp_connection_open(char */*notnull*/ host); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Sends a [SPCommand] to the display using the [SPConnection]. |  * Sends a [SPCommand] to the display using the [SPConnection]. | ||||||
|  | @ -1621,8 +1619,8 @@ UdpConnection *sp_connection_open(const char *host); | ||||||
|  * - `command` points to a valid instance of [SPPacket] |  * - `command` points to a valid instance of [SPPacket] | ||||||
|  * - `command` is not used concurrently or after this call |  * - `command` is not used concurrently or after this call | ||||||
|  */ |  */ | ||||||
| bool sp_connection_send_command(const UdpConnection *connection, | bool sp_connection_send_command(UdpConnection */*notnull*/ connection, | ||||||
|                                 Command *command); |                                 Command */*notnull*/ command); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Sends a [SPPacket] to the display using the [SPConnection]. |  * Sends a [SPPacket] to the display using the [SPConnection]. | ||||||
|  | @ -1644,7 +1642,8 @@ bool sp_connection_send_command(const UdpConnection *connection, | ||||||
|  * - `packet` points to a valid instance of [SPPacket] |  * - `packet` points to a valid instance of [SPPacket] | ||||||
|  * - `packet` is not used concurrently or after this call |  * - `packet` is not used concurrently or after this call | ||||||
|  */ |  */ | ||||||
| bool sp_connection_send_packet(const UdpConnection *connection, Packet *packet); | bool sp_connection_send_packet(UdpConnection */*notnull*/ connection, | ||||||
|  |                                Packet */*notnull*/ packet); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Clones a [SPCp437Grid]. |  * Clones a [SPCp437Grid]. | ||||||
|  | @ -1664,7 +1663,7 @@ bool sp_connection_send_packet(const UdpConnection *connection, Packet *packet); | ||||||
|  * - 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_cp437_grid_free`. |  *   by explicitly calling `sp_cp437_grid_free`. | ||||||
|  */ |  */ | ||||||
| Cp437Grid *sp_cp437_grid_clone(const Cp437Grid *cp437_grid); | Cp437Grid */*notnull*/ sp_cp437_grid_clone(Cp437Grid */*notnull*/ cp437_grid); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Sets the value of all cells in the [SPCp437Grid]. |  * Sets the value of all cells in the [SPCp437Grid]. | ||||||
|  | @ -1685,7 +1684,7 @@ Cp437Grid *sp_cp437_grid_clone(const Cp437Grid *cp437_grid); | ||||||
|  * - `cp437_grid` points to a valid [SPCp437Grid] |  * - `cp437_grid` points to a valid [SPCp437Grid] | ||||||
|  * - `cp437_grid` is not written to or read from concurrently |  * - `cp437_grid` is not written to or read from concurrently | ||||||
|  */ |  */ | ||||||
| void sp_cp437_grid_fill(Cp437Grid *cp437_grid, uint8_t value); | void sp_cp437_grid_fill(Cp437Grid */*notnull*/ cp437_grid, uint8_t value); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Deallocates a [SPCp437Grid]. |  * Deallocates a [SPCp437Grid]. | ||||||
|  | @ -1704,7 +1703,7 @@ void sp_cp437_grid_fill(Cp437Grid *cp437_grid, uint8_t value); | ||||||
|  * |  * | ||||||
|  * [SPCommand]: [crate::SPCommand] |  * [SPCommand]: [crate::SPCommand] | ||||||
|  */ |  */ | ||||||
| void sp_cp437_grid_free(Cp437Grid *cp437_grid); | void sp_cp437_grid_free(Cp437Grid */*notnull*/ cp437_grid); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Gets the current value at the specified position. |  * Gets the current value at the specified position. | ||||||
|  | @ -1726,7 +1725,9 @@ void sp_cp437_grid_free(Cp437Grid *cp437_grid); | ||||||
|  * - `cp437_grid` points to a valid [SPCp437Grid] |  * - `cp437_grid` points to a valid [SPCp437Grid] | ||||||
|  * - `cp437_grid` is not written to concurrently |  * - `cp437_grid` is not written to concurrently | ||||||
|  */ |  */ | ||||||
| uint8_t sp_cp437_grid_get(const Cp437Grid *cp437_grid, size_t x, size_t y); | uint8_t sp_cp437_grid_get(Cp437Grid */*notnull*/ cp437_grid, | ||||||
|  |                           size_t x, | ||||||
|  |                           size_t y); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Gets the height of the [SPCp437Grid] instance. |  * Gets the height of the [SPCp437Grid] instance. | ||||||
|  | @ -1745,7 +1746,7 @@ uint8_t sp_cp437_grid_get(const Cp437Grid *cp437_grid, size_t x, size_t y); | ||||||
|  * |  * | ||||||
|  * - `cp437_grid` points to a valid [SPCp437Grid] |  * - `cp437_grid` points to a valid [SPCp437Grid] | ||||||
|  */ |  */ | ||||||
| size_t sp_cp437_grid_height(const Cp437Grid *cp437_grid); | size_t sp_cp437_grid_height(Cp437Grid */*notnull*/ cp437_grid); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Loads a [SPCp437Grid] with the specified dimensions from the provided data. |  * Loads a [SPCp437Grid] with the specified dimensions from the provided data. | ||||||
|  | @ -1768,8 +1769,7 @@ size_t sp_cp437_grid_height(const Cp437Grid *cp437_grid); | ||||||
|  */ |  */ | ||||||
| Cp437Grid *sp_cp437_grid_load(size_t width, | Cp437Grid *sp_cp437_grid_load(size_t width, | ||||||
|                               size_t height, |                               size_t height, | ||||||
|                               const uint8_t *data, |                               SPByteSlice data); | ||||||
|                               size_t data_length); |  | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Creates a new [SPCp437Grid] with the specified dimensions. |  * Creates a new [SPCp437Grid] with the specified dimensions. | ||||||
|  | @ -1783,8 +1783,8 @@ Cp437Grid *sp_cp437_grid_load(size_t width, | ||||||
|  * - 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_cp437_grid_free`. |  *   by explicitly calling `sp_cp437_grid_free`. | ||||||
|  */ |  */ | ||||||
| Cp437Grid *sp_cp437_grid_new(size_t width, | Cp437Grid */*notnull*/ sp_cp437_grid_new(size_t width, | ||||||
|                              size_t height); |                                          size_t height); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Sets the value of the specified position in the [SPCp437Grid]. |  * Sets the value of the specified position in the [SPCp437Grid]. | ||||||
|  | @ -1811,7 +1811,7 @@ Cp437Grid *sp_cp437_grid_new(size_t width, | ||||||
|  * |  * | ||||||
|  * [SPBitVec]: [crate::SPBitVec] |  * [SPBitVec]: [crate::SPBitVec] | ||||||
|  */ |  */ | ||||||
| void sp_cp437_grid_set(Cp437Grid *cp437_grid, | void sp_cp437_grid_set(Cp437Grid */*notnull*/ cp437_grid, | ||||||
|                        size_t x, |                        size_t x, | ||||||
|                        size_t y, |                        size_t y, | ||||||
|                        uint8_t value); |                        uint8_t value); | ||||||
|  | @ -1833,7 +1833,7 @@ void sp_cp437_grid_set(Cp437Grid *cp437_grid, | ||||||
|  * - the returned memory range is never accessed after the passed [SPCp437Grid] has been freed |  * - the returned memory range is never accessed after the passed [SPCp437Grid] has been freed | ||||||
|  * - the returned memory range is never accessed concurrently, either via the [SPCp437Grid] or directly |  * - the returned memory range is never accessed concurrently, either via the [SPCp437Grid] or directly | ||||||
|  */ |  */ | ||||||
| SPByteSlice sp_cp437_grid_unsafe_data_ref(Cp437Grid *cp437_grid); | SPByteSlice sp_cp437_grid_unsafe_data_ref(Cp437Grid */*notnull*/ cp437_grid); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Gets the width of the [SPCp437Grid] instance. |  * Gets the width of the [SPCp437Grid] instance. | ||||||
|  | @ -1852,7 +1852,7 @@ SPByteSlice sp_cp437_grid_unsafe_data_ref(Cp437Grid *cp437_grid); | ||||||
|  * |  * | ||||||
|  * - `cp437_grid` points to a valid [SPCp437Grid] |  * - `cp437_grid` points to a valid [SPCp437Grid] | ||||||
|  */ |  */ | ||||||
| size_t sp_cp437_grid_width(const Cp437Grid *cp437_grid); | size_t sp_cp437_grid_width(Cp437Grid */*notnull*/ cp437_grid); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Clones a [SPPacket]. |  * Clones a [SPPacket]. | ||||||
|  | @ -1872,7 +1872,7 @@ size_t sp_cp437_grid_width(const Cp437Grid *cp437_grid); | ||||||
|  * - 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_packet_free`. |  *   by explicitly calling `sp_packet_free`. | ||||||
|  */ |  */ | ||||||
| Packet *sp_packet_clone(const Packet *packet); | Packet */*notnull*/ sp_packet_clone(Packet */*notnull*/ packet); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Deallocates a [SPPacket]. |  * Deallocates a [SPPacket]. | ||||||
|  | @ -1888,7 +1888,7 @@ Packet *sp_packet_clone(const Packet *packet); | ||||||
|  * - `packet` points to a valid [SPPacket] |  * - `packet` points to a valid [SPPacket] | ||||||
|  * - `packet` is not used concurrently or after this call |  * - `packet` is not used concurrently or after this call | ||||||
|  */ |  */ | ||||||
| void sp_packet_free(Packet *packet); | void sp_packet_free(Packet */*notnull*/ packet); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Turns a [SPCommand] into a [SPPacket]. |  * Turns a [SPCommand] into a [SPPacket]. | ||||||
|  | @ -1909,7 +1909,7 @@ void sp_packet_free(Packet *packet); | ||||||
|  * - the returned [SPPacket] instance is freed in some way, either by using a consuming function or |  * - the returned [SPPacket] instance is freed in some way, either by using a consuming function or | ||||||
|  *   by explicitly calling `sp_packet_free`. |  *   by explicitly calling `sp_packet_free`. | ||||||
|  */ |  */ | ||||||
| Packet *sp_packet_from_command(Command *command); | Packet *sp_packet_from_command(Command */*notnull*/ command); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Creates a raw [SPPacket] from parts. |  * Creates a raw [SPPacket] from parts. | ||||||
|  | @ -1937,15 +1937,14 @@ Packet *sp_packet_from_command(Command *command); | ||||||
|  * - the returned [SPPacket] instance is freed in some way, either by using a consuming function or |  * - the returned [SPPacket] instance is freed in some way, either by using a consuming function or | ||||||
|  *   by explicitly calling [sp_packet_free]. |  *   by explicitly calling [sp_packet_free]. | ||||||
|  */ |  */ | ||||||
| Packet *sp_packet_from_parts(Header header, | Packet */*notnull*/ sp_packet_from_parts(Header header, | ||||||
|                              const uint8_t *payload, |                                          const SPByteSlice *payload); | ||||||
|                              size_t payload_len); |  | ||||||
| 
 | 
 | ||||||
| Header *sp_packet_get_header(Packet *packet); | Header */*notnull*/ sp_packet_get_header(Packet */*notnull*/ packet); | ||||||
| 
 | 
 | ||||||
| SPByteSlice sp_packet_get_payload(Packet *packet); | SPByteSlice sp_packet_get_payload(Packet */*notnull*/ packet); | ||||||
| 
 | 
 | ||||||
| void sp_packet_set_payload(Packet *packet, SPByteSlice data); | void sp_packet_set_payload(Packet */*notnull*/ packet, SPByteSlice data); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Tries to load a [SPPacket] from the passed array with the specified length. |  * Tries to load a [SPPacket] from the passed array with the specified length. | ||||||
|  | @ -1965,10 +1964,9 @@ void sp_packet_set_payload(Packet *packet, SPByteSlice data); | ||||||
|  * - the returned [SPPacket] instance is freed in some way, either by using a consuming function or |  * - the returned [SPPacket] instance is freed in some way, either by using a consuming function or | ||||||
|  *   by explicitly calling `sp_packet_free`. |  *   by explicitly calling `sp_packet_free`. | ||||||
|  */ |  */ | ||||||
| Packet *sp_packet_try_load(const uint8_t *data, | Packet *sp_packet_try_load(SPByteSlice data); | ||||||
|                            size_t length); |  | ||||||
| 
 | 
 | ||||||
| void sp_packet_write_to(const Packet *packet, SPByteSlice buffer); | void sp_packet_write_to(Packet */*notnull*/ packet, SPByteSlice buffer); | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| }  // extern "C"
 | }  // extern "C"
 | ||||||
|  |  | ||||||
|  | @ -13,7 +13,7 @@ | ||||||
| //! sp_bitmap_free(grid);
 | //! sp_bitmap_free(grid);
 | ||||||
| //! ```
 | //! ```
 | ||||||
| 
 | 
 | ||||||
| use servicepoint::{DataRef, Grid}; | use servicepoint::{Bitmap, DataRef, Grid}; | ||||||
| use std::ptr::NonNull; | use std::ptr::NonNull; | ||||||
| 
 | 
 | ||||||
| use crate::byte_slice::SPByteSlice; | use crate::byte_slice::SPByteSlice; | ||||||
|  | @ -43,8 +43,8 @@ use crate::byte_slice::SPByteSlice; | ||||||
| pub unsafe extern "C" fn sp_bitmap_new( | pub unsafe extern "C" fn sp_bitmap_new( | ||||||
|     width: usize, |     width: usize, | ||||||
|     height: usize, |     height: usize, | ||||||
| ) -> *mut servicepoint::Bitmap { | ) -> *mut Bitmap { | ||||||
|     if let Some(bitmap) = servicepoint::Bitmap::new(width, height) { |     if let Some(bitmap) = Bitmap::new(width, height) { | ||||||
|         Box::leak(Box::new(bitmap)) |         Box::leak(Box::new(bitmap)) | ||||||
|     } else { |     } else { | ||||||
|         std::ptr::null_mut() |         std::ptr::null_mut() | ||||||
|  | @ -62,9 +62,8 @@ pub unsafe extern "C" fn sp_bitmap_new( | ||||||
| /// - the returned instance is freed in some way, either by using a consuming function or
 | /// - the returned instance is freed in some way, either by using a consuming function or
 | ||||||
| ///   by explicitly calling [sp_bitmap_free].
 | ///   by explicitly calling [sp_bitmap_free].
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bitmap_new_screen_sized( | pub unsafe extern "C" fn sp_bitmap_new_screen_sized() -> NonNull<Bitmap> { | ||||||
| ) -> NonNull<servicepoint::Bitmap> { |     let result = Box::new(Bitmap::max_sized()); | ||||||
|     let result = Box::new(servicepoint::Bitmap::max_sized()); |  | ||||||
|     NonNull::from(Box::leak(result)) |     NonNull::from(Box::leak(result)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -99,12 +98,10 @@ pub unsafe extern "C" fn sp_bitmap_new_screen_sized( | ||||||
| pub unsafe extern "C" fn sp_bitmap_load( | pub unsafe extern "C" fn sp_bitmap_load( | ||||||
|     width: usize, |     width: usize, | ||||||
|     height: usize, |     height: usize, | ||||||
|     data: *const u8, |     data: SPByteSlice, | ||||||
|     data_length: usize, | ) -> *mut Bitmap { | ||||||
| ) -> *mut servicepoint::Bitmap { |     let data = unsafe { data.as_slice() }; | ||||||
|     assert!(!data.is_null()); |     if let Ok(bitmap) = Bitmap::load(width, height, data) { | ||||||
|     let data = unsafe { std::slice::from_raw_parts(data, data_length) }; |  | ||||||
|     if let Ok(bitmap) = servicepoint::Bitmap::load(width, height, data) { |  | ||||||
|         Box::leak(Box::new(bitmap)) |         Box::leak(Box::new(bitmap)) | ||||||
|     } else { |     } else { | ||||||
|         std::ptr::null_mut() |         std::ptr::null_mut() | ||||||
|  | @ -129,10 +126,9 @@ pub unsafe extern "C" fn sp_bitmap_load( | ||||||
| ///   by explicitly calling `sp_bitmap_free`.
 | ///   by explicitly calling `sp_bitmap_free`.
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bitmap_clone( | pub unsafe extern "C" fn sp_bitmap_clone( | ||||||
|     bitmap: *const servicepoint::Bitmap, |     bitmap: NonNull<Bitmap>, | ||||||
| ) -> NonNull<servicepoint::Bitmap> { | ) -> NonNull<Bitmap> { | ||||||
|     assert!(!bitmap.is_null()); |     let result = Box::new(unsafe { bitmap.as_ref().clone() }); | ||||||
|     let result = Box::new(unsafe { (*bitmap).clone() }); |  | ||||||
|     NonNull::from(Box::leak(result)) |     NonNull::from(Box::leak(result)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -147,14 +143,11 @@ pub unsafe extern "C" fn sp_bitmap_clone( | ||||||
| /// The caller has to make sure that:
 | /// The caller has to make sure that:
 | ||||||
| ///
 | ///
 | ||||||
| /// - `bitmap` points to a valid [SPBitmap]
 | /// - `bitmap` points to a valid [SPBitmap]
 | ||||||
| /// - `bitmap` is not used concurrently or after bitmap call
 |  | ||||||
| /// - `bitmap` was not passed to another consuming function, e.g. to create a [SPCommand]
 |  | ||||||
| ///
 | ///
 | ||||||
| /// [SPCommand]: [crate::SPCommand]
 | /// [SPCommand]: [crate::SPCommand]
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bitmap_free(bitmap: *mut servicepoint::Bitmap) { | pub unsafe extern "C" fn sp_bitmap_free(bitmap: NonNull<Bitmap>) { | ||||||
|     assert!(!bitmap.is_null()); |     _ = unsafe { Box::from_raw(bitmap.as_ptr()) }; | ||||||
|     _ = unsafe { Box::from_raw(bitmap) }; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets the current value at the specified position in the [SPBitmap].
 | /// Gets the current value at the specified position in the [SPBitmap].
 | ||||||
|  | @ -177,12 +170,11 @@ pub unsafe extern "C" fn sp_bitmap_free(bitmap: *mut servicepoint::Bitmap) { | ||||||
| /// - `bitmap` is not written to concurrently
 | /// - `bitmap` is not written to concurrently
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bitmap_get( | pub unsafe extern "C" fn sp_bitmap_get( | ||||||
|     bitmap: *const servicepoint::Bitmap, |     bitmap: NonNull<Bitmap>, | ||||||
|     x: usize, |     x: usize, | ||||||
|     y: usize, |     y: usize, | ||||||
| ) -> bool { | ) -> bool { | ||||||
|     assert!(!bitmap.is_null()); |     unsafe { bitmap.as_ref().get(x, y) } | ||||||
|     unsafe { (*bitmap).get(x, y) } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Sets the value of the specified position in the [SPBitmap].
 | /// Sets the value of the specified position in the [SPBitmap].
 | ||||||
|  | @ -208,13 +200,12 @@ pub unsafe extern "C" fn sp_bitmap_get( | ||||||
| /// - `bitmap` is not written to or read from concurrently
 | /// - `bitmap` is not written to or read from concurrently
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bitmap_set( | pub unsafe extern "C" fn sp_bitmap_set( | ||||||
|     bitmap: *mut servicepoint::Bitmap, |     bitmap: NonNull<Bitmap>, | ||||||
|     x: usize, |     x: usize, | ||||||
|     y: usize, |     y: usize, | ||||||
|     value: bool, |     value: bool, | ||||||
| ) { | ) { | ||||||
|     assert!(!bitmap.is_null()); |     unsafe { (*bitmap.as_ptr()).set(x, y, value) }; | ||||||
|     unsafe { (*bitmap).set(x, y, value) }; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Sets the state of all pixels in the [SPBitmap].
 | /// Sets the state of all pixels in the [SPBitmap].
 | ||||||
|  | @ -235,12 +226,8 @@ pub unsafe extern "C" fn sp_bitmap_set( | ||||||
| /// - `bitmap` points to a valid [SPBitmap]
 | /// - `bitmap` points to a valid [SPBitmap]
 | ||||||
| /// - `bitmap` is not written to or read from concurrently
 | /// - `bitmap` is not written to or read from concurrently
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bitmap_fill( | pub unsafe extern "C" fn sp_bitmap_fill(bitmap: NonNull<Bitmap>, value: bool) { | ||||||
|     bitmap: *mut servicepoint::Bitmap, |     unsafe { (*bitmap.as_ptr()).fill(value) }; | ||||||
|     value: bool, |  | ||||||
| ) { |  | ||||||
|     assert!(!bitmap.is_null()); |  | ||||||
|     unsafe { (*bitmap).fill(value) }; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets the width in pixels of the [SPBitmap] instance.
 | /// Gets the width in pixels of the [SPBitmap] instance.
 | ||||||
|  | @ -259,11 +246,8 @@ pub unsafe extern "C" fn sp_bitmap_fill( | ||||||
| ///
 | ///
 | ||||||
| /// - `bitmap` points to a valid [SPBitmap]
 | /// - `bitmap` points to a valid [SPBitmap]
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bitmap_width( | pub unsafe extern "C" fn sp_bitmap_width(bitmap: NonNull<Bitmap>) -> usize { | ||||||
|     bitmap: *const servicepoint::Bitmap, |     unsafe { bitmap.as_ref().width() } | ||||||
| ) -> usize { |  | ||||||
|     assert!(!bitmap.is_null()); |  | ||||||
|     unsafe { (*bitmap).width() } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets the height in pixels of the [SPBitmap] instance.
 | /// Gets the height in pixels of the [SPBitmap] instance.
 | ||||||
|  | @ -282,11 +266,8 @@ pub unsafe extern "C" fn sp_bitmap_width( | ||||||
| ///
 | ///
 | ||||||
| /// - `bitmap` points to a valid [SPBitmap]
 | /// - `bitmap` points to a valid [SPBitmap]
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bitmap_height( | pub unsafe extern "C" fn sp_bitmap_height(bitmap: NonNull<Bitmap>) -> usize { | ||||||
|     bitmap: *const servicepoint::Bitmap, |     unsafe { bitmap.as_ref().height() } | ||||||
| ) -> usize { |  | ||||||
|     assert!(!bitmap.is_null()); |  | ||||||
|     unsafe { (*bitmap).height() } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets an unsafe reference to the data of the [SPBitmap] instance.
 | /// Gets an unsafe reference to the data of the [SPBitmap] instance.
 | ||||||
|  | @ -304,8 +285,7 @@ pub unsafe extern "C" fn sp_bitmap_height( | ||||||
| /// - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly
 | /// - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bitmap_unsafe_data_ref( | pub unsafe extern "C" fn sp_bitmap_unsafe_data_ref( | ||||||
|     bitmap: *mut servicepoint::Bitmap, |     mut bitmap: NonNull<Bitmap>, | ||||||
| ) -> SPByteSlice { | ) -> SPByteSlice { | ||||||
|     assert!(!bitmap.is_null()); |     unsafe { SPByteSlice::from_slice(bitmap.as_mut().data_ref_mut()) } | ||||||
|     unsafe { SPByteSlice::from_slice((*bitmap).data_ref_mut()) } |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -13,19 +13,7 @@ use std::ptr::NonNull; | ||||||
| /// sp_bitvec_set(vec, 5, true);
 | /// sp_bitvec_set(vec, 5, true);
 | ||||||
| /// sp_bitvec_free(vec);
 | /// sp_bitvec_free(vec);
 | ||||||
| /// ```
 | /// ```
 | ||||||
| pub struct SPBitVec(servicepoint::BitVecU8Msb0); | pub struct SPBitVec(pub(crate) servicepoint::BitVecU8Msb0); | ||||||
| 
 |  | ||||||
| impl From<servicepoint::BitVecU8Msb0> for SPBitVec { |  | ||||||
|     fn from(actual: servicepoint::BitVecU8Msb0) -> Self { |  | ||||||
|         Self(actual) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl From<SPBitVec> for servicepoint::BitVecU8Msb0 { |  | ||||||
|     fn from(value: SPBitVec) -> Self { |  | ||||||
|         value.0 |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| impl Clone for SPBitVec { | impl Clone for SPBitVec { | ||||||
|     fn clone(&self) -> Self { |     fn clone(&self) -> Self { | ||||||
|  | @ -53,7 +41,8 @@ impl Clone for SPBitVec { | ||||||
| ///   by explicitly calling `sp_bitvec_free`.
 | ///   by explicitly calling `sp_bitvec_free`.
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bitvec_new(size: usize) -> NonNull<SPBitVec> { | pub unsafe extern "C" fn sp_bitvec_new(size: usize) -> NonNull<SPBitVec> { | ||||||
|     let result = Box::new(SPBitVec(servicepoint::BitVecU8Msb0::repeat(false, size))); |     let result = | ||||||
|  |         Box::new(SPBitVec(servicepoint::BitVecU8Msb0::repeat(false, size))); | ||||||
|     NonNull::from(Box::leak(result)) |     NonNull::from(Box::leak(result)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -75,12 +64,11 @@ pub unsafe extern "C" fn sp_bitvec_new(size: usize) -> NonNull<SPBitVec> { | ||||||
| ///   by explicitly calling `sp_bitvec_free`.
 | ///   by explicitly calling `sp_bitvec_free`.
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bitvec_load( | pub unsafe extern "C" fn sp_bitvec_load( | ||||||
|     data: *const u8, |     data: SPByteSlice, | ||||||
|     data_length: usize, |  | ||||||
| ) -> NonNull<SPBitVec> { | ) -> NonNull<SPBitVec> { | ||||||
|     assert!(!data.is_null()); |     let data = unsafe { data.as_slice() }; | ||||||
|     let data = unsafe { std::slice::from_raw_parts(data, data_length) }; |     let result = | ||||||
|     let result = Box::new(SPBitVec(servicepoint::BitVecU8Msb0::from_slice(data))); |         Box::new(SPBitVec(servicepoint::BitVecU8Msb0::from_slice(data))); | ||||||
|     NonNull::from(Box::leak(result)) |     NonNull::from(Box::leak(result)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -102,10 +90,9 @@ pub unsafe extern "C" fn sp_bitvec_load( | ||||||
| ///   by explicitly calling `sp_bitvec_free`.
 | ///   by explicitly calling `sp_bitvec_free`.
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bitvec_clone( | pub unsafe extern "C" fn sp_bitvec_clone( | ||||||
|     bit_vec: *const SPBitVec, |     bit_vec: NonNull<SPBitVec>, | ||||||
| ) -> NonNull<SPBitVec> { | ) -> NonNull<SPBitVec> { | ||||||
|     assert!(!bit_vec.is_null()); |     let result = Box::new(unsafe { bit_vec.as_ref().clone() }); | ||||||
|     let result = Box::new(unsafe { (*bit_vec).clone() }); |  | ||||||
|     NonNull::from(Box::leak(result)) |     NonNull::from(Box::leak(result)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -125,9 +112,8 @@ pub unsafe extern "C" fn sp_bitvec_clone( | ||||||
| ///
 | ///
 | ||||||
| /// [SPCommand]: [crate::SPCommand]
 | /// [SPCommand]: [crate::SPCommand]
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bitvec_free(bit_vec: *mut SPBitVec) { | pub unsafe extern "C" fn sp_bitvec_free(bit_vec: NonNull<SPBitVec>) { | ||||||
|     assert!(!bit_vec.is_null()); |     _ = unsafe { Box::from_raw(bit_vec.as_ptr()) }; | ||||||
|     _ = unsafe { Box::from_raw(bit_vec) }; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets the value of a bit from the [SPBitVec].
 | /// Gets the value of a bit from the [SPBitVec].
 | ||||||
|  | @ -152,11 +138,10 @@ pub unsafe extern "C" fn sp_bitvec_free(bit_vec: *mut SPBitVec) { | ||||||
| /// - `bit_vec` is not written to concurrently
 | /// - `bit_vec` is not written to concurrently
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bitvec_get( | pub unsafe extern "C" fn sp_bitvec_get( | ||||||
|     bit_vec: *const SPBitVec, |     bit_vec: NonNull<SPBitVec>, | ||||||
|     index: usize, |     index: usize, | ||||||
| ) -> bool { | ) -> bool { | ||||||
|     assert!(!bit_vec.is_null()); |     unsafe { *bit_vec.as_ref().0.get(index).unwrap() } | ||||||
|     unsafe { *(*bit_vec).0.get(index).unwrap() } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Sets the value of a bit in the [SPBitVec].
 | /// Sets the value of a bit in the [SPBitVec].
 | ||||||
|  | @ -180,12 +165,11 @@ pub unsafe extern "C" fn sp_bitvec_get( | ||||||
| /// - `bit_vec` is not written to or read from concurrently
 | /// - `bit_vec` is not written to or read from concurrently
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bitvec_set( | pub unsafe extern "C" fn sp_bitvec_set( | ||||||
|     bit_vec: *mut SPBitVec, |     bit_vec: NonNull<SPBitVec>, | ||||||
|     index: usize, |     index: usize, | ||||||
|     value: bool, |     value: bool, | ||||||
| ) { | ) { | ||||||
|     assert!(!bit_vec.is_null()); |     unsafe { (*bit_vec.as_ptr()).0.set(index, value) } | ||||||
|     unsafe { (*bit_vec).0.set(index, value) } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Sets the value of all bits in the [SPBitVec].
 | /// Sets the value of all bits in the [SPBitVec].
 | ||||||
|  | @ -206,9 +190,11 @@ pub unsafe extern "C" fn sp_bitvec_set( | ||||||
| /// - `bit_vec` points to a valid [SPBitVec]
 | /// - `bit_vec` points to a valid [SPBitVec]
 | ||||||
| /// - `bit_vec` is not written to or read from concurrently
 | /// - `bit_vec` is not written to or read from concurrently
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bitvec_fill(bit_vec: *mut SPBitVec, value: bool) { | pub unsafe extern "C" fn sp_bitvec_fill( | ||||||
|     assert!(!bit_vec.is_null()); |     bit_vec: NonNull<SPBitVec>, | ||||||
|     unsafe { (*bit_vec).0.fill(value) } |     value: bool, | ||||||
|  | ) { | ||||||
|  |     unsafe { (*bit_vec.as_ptr()).0.fill(value) } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets the length of the [SPBitVec] in bits.
 | /// Gets the length of the [SPBitVec] in bits.
 | ||||||
|  | @ -227,9 +213,8 @@ pub unsafe extern "C" fn sp_bitvec_fill(bit_vec: *mut SPBitVec, value: bool) { | ||||||
| ///
 | ///
 | ||||||
| /// - `bit_vec` points to a valid [SPBitVec]
 | /// - `bit_vec` points to a valid [SPBitVec]
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bitvec_len(bit_vec: *const SPBitVec) -> usize { | pub unsafe extern "C" fn sp_bitvec_len(bit_vec: NonNull<SPBitVec>) -> usize { | ||||||
|     assert!(!bit_vec.is_null()); |     unsafe { bit_vec.as_ref().0.len() } | ||||||
|     unsafe { (*bit_vec).0.len() } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Returns true if length is 0.
 | /// Returns true if length is 0.
 | ||||||
|  | @ -248,9 +233,10 @@ pub unsafe extern "C" fn sp_bitvec_len(bit_vec: *const SPBitVec) -> usize { | ||||||
| ///
 | ///
 | ||||||
| /// - `bit_vec` points to a valid [SPBitVec]
 | /// - `bit_vec` points to a valid [SPBitVec]
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bitvec_is_empty(bit_vec: *const SPBitVec) -> bool { | pub unsafe extern "C" fn sp_bitvec_is_empty( | ||||||
|     assert!(!bit_vec.is_null()); |     bit_vec: NonNull<SPBitVec>, | ||||||
|     unsafe { (*bit_vec).0.is_empty() } | ) -> bool { | ||||||
|  |     unsafe { bit_vec.as_ref().0.is_empty() } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets an unsafe reference to the data of the [SPBitVec] instance.
 | /// Gets an unsafe reference to the data of the [SPBitVec] instance.
 | ||||||
|  | @ -272,8 +258,7 @@ pub unsafe extern "C" fn sp_bitvec_is_empty(bit_vec: *const SPBitVec) -> bool { | ||||||
| /// - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly
 | /// - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_bitvec_unsafe_data_ref( | pub unsafe extern "C" fn sp_bitvec_unsafe_data_ref( | ||||||
|     bit_vec: *mut SPBitVec, |     bit_vec: NonNull<SPBitVec>, | ||||||
| ) -> SPByteSlice { | ) -> SPByteSlice { | ||||||
|     assert!(!bit_vec.is_null()); |     unsafe { SPByteSlice::from_slice((*bit_vec.as_ptr()).0.as_raw_mut_slice()) } | ||||||
|     unsafe { SPByteSlice::from_slice((*bit_vec).0.as_raw_mut_slice() ) } |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -32,7 +32,6 @@ pub const SP_BRIGHTNESS_MAX: u8 = 11; | ||||||
| /// Count of possible brightness values
 | /// Count of possible brightness values
 | ||||||
| pub const SP_BRIGHTNESS_LEVELS: u8 = 12; | pub const SP_BRIGHTNESS_LEVELS: u8 = 12; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| /// Creates a new [SPBrightnessGrid] with the specified dimensions.
 | /// Creates a new [SPBrightnessGrid] with the specified dimensions.
 | ||||||
| ///
 | ///
 | ||||||
| /// returns: [SPBrightnessGrid] initialized to 0. Will never return NULL.
 | /// returns: [SPBrightnessGrid] initialized to 0. Will never return NULL.
 | ||||||
|  | @ -48,9 +47,7 @@ pub unsafe extern "C" fn sp_brightness_grid_new( | ||||||
|     width: usize, |     width: usize, | ||||||
|     height: usize, |     height: usize, | ||||||
| ) -> NonNull<BrightnessGrid> { | ) -> NonNull<BrightnessGrid> { | ||||||
|     let result = Box::new(servicepoint::BrightnessGrid::new( |     let result = Box::new(BrightnessGrid::new(width, height)); | ||||||
|         width, height, |  | ||||||
|     )); |  | ||||||
|     NonNull::from(Box::leak(result)) |     NonNull::from(Box::leak(result)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -75,16 +72,14 @@ pub unsafe extern "C" fn sp_brightness_grid_new( | ||||||
| pub unsafe extern "C" fn sp_brightness_grid_load( | pub unsafe extern "C" fn sp_brightness_grid_load( | ||||||
|     width: usize, |     width: usize, | ||||||
|     height: usize, |     height: usize, | ||||||
|     data: *const u8, |     data: SPByteSlice, | ||||||
|     data_length: usize, |  | ||||||
| ) -> *mut BrightnessGrid { | ) -> *mut BrightnessGrid { | ||||||
|     assert!(!data.is_null()); |     let data = unsafe { data.as_slice() }; | ||||||
|     let data = unsafe { std::slice::from_raw_parts(data, data_length) }; |  | ||||||
|     let grid = match servicepoint::ByteGrid::load(width, height, data) { |     let grid = match servicepoint::ByteGrid::load(width, height, data) { | ||||||
|         None => return std::ptr::null_mut(), |         None => return std::ptr::null_mut(), | ||||||
|         Some(grid) => grid, |         Some(grid) => grid, | ||||||
|     }; |     }; | ||||||
|     if let Ok(grid) = servicepoint::BrightnessGrid::try_from(grid) { |     if let Ok(grid) = BrightnessGrid::try_from(grid) { | ||||||
|         Box::leak(Box::new(grid)) |         Box::leak(Box::new(grid)) | ||||||
|     } else { |     } else { | ||||||
|         std::ptr::null_mut() |         std::ptr::null_mut() | ||||||
|  | @ -113,10 +108,9 @@ pub unsafe extern "C" fn sp_brightness_grid_load( | ||||||
| ///   by explicitly calling `sp_brightness_grid_free`.
 | ///   by explicitly calling `sp_brightness_grid_free`.
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_brightness_grid_clone( | pub unsafe extern "C" fn sp_brightness_grid_clone( | ||||||
|     brightness_grid: *const BrightnessGrid, |     brightness_grid: NonNull<BrightnessGrid>, | ||||||
| ) -> NonNull<BrightnessGrid> { | ) -> NonNull<BrightnessGrid> { | ||||||
|     assert!(!brightness_grid.is_null()); |     let result = Box::new(unsafe { brightness_grid.as_ref().clone() }); | ||||||
|     let result = Box::new(unsafe { (*brightness_grid).clone() }); |  | ||||||
|     NonNull::from(Box::leak(result)) |     NonNull::from(Box::leak(result)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -141,10 +135,9 @@ pub unsafe extern "C" fn sp_brightness_grid_clone( | ||||||
| /// [SPCommand]: [crate::SPCommand]
 | /// [SPCommand]: [crate::SPCommand]
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_brightness_grid_free( | pub unsafe extern "C" fn sp_brightness_grid_free( | ||||||
|     brightness_grid: *mut BrightnessGrid, |     brightness_grid: NonNull<BrightnessGrid>, | ||||||
| ) { | ) { | ||||||
|     assert!(!brightness_grid.is_null()); |     _ = unsafe { Box::from_raw(brightness_grid.as_ptr()) }; | ||||||
|     _ = unsafe { Box::from_raw(brightness_grid) }; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets the current value at the specified position.
 | /// Gets the current value at the specified position.
 | ||||||
|  | @ -169,12 +162,11 @@ pub unsafe extern "C" fn sp_brightness_grid_free( | ||||||
| /// - `brightness_grid` is not written to concurrently
 | /// - `brightness_grid` is not written to concurrently
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_brightness_grid_get( | pub unsafe extern "C" fn sp_brightness_grid_get( | ||||||
|     brightness_grid: *const BrightnessGrid, |     brightness_grid: NonNull<BrightnessGrid>, | ||||||
|     x: usize, |     x: usize, | ||||||
|     y: usize, |     y: usize, | ||||||
| ) -> u8 { | ) -> u8 { | ||||||
|     assert!(!brightness_grid.is_null()); |     unsafe { brightness_grid.as_ref().get(x, y) }.into() | ||||||
|     unsafe { (*brightness_grid).get(x, y) }.into() |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Sets the value of the specified position in the [SPBrightnessGrid].
 | /// Sets the value of the specified position in the [SPBrightnessGrid].
 | ||||||
|  | @ -201,15 +193,14 @@ pub unsafe extern "C" fn sp_brightness_grid_get( | ||||||
| /// - `brightness_grid` is not written to or read from concurrently
 | /// - `brightness_grid` is not written to or read from concurrently
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_brightness_grid_set( | pub unsafe extern "C" fn sp_brightness_grid_set( | ||||||
|     brightness_grid: *mut BrightnessGrid, |     brightness_grid: NonNull<BrightnessGrid>, | ||||||
|     x: usize, |     x: usize, | ||||||
|     y: usize, |     y: usize, | ||||||
|     value: u8, |     value: u8, | ||||||
| ) { | ) { | ||||||
|     assert!(!brightness_grid.is_null()); |  | ||||||
|     let brightness = servicepoint::Brightness::try_from(value) |     let brightness = servicepoint::Brightness::try_from(value) | ||||||
|         .expect("invalid brightness value"); |         .expect("invalid brightness value"); | ||||||
|     unsafe { (*brightness_grid).set(x, y, brightness) }; |     unsafe { (*brightness_grid.as_ptr()).set(x, y, brightness) }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Sets the value of all cells in the [SPBrightnessGrid].
 | /// Sets the value of all cells in the [SPBrightnessGrid].
 | ||||||
|  | @ -232,13 +223,12 @@ pub unsafe extern "C" fn sp_brightness_grid_set( | ||||||
| /// - `brightness_grid` is not written to or read from concurrently
 | /// - `brightness_grid` is not written to or read from concurrently
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_brightness_grid_fill( | pub unsafe extern "C" fn sp_brightness_grid_fill( | ||||||
|     brightness_grid: *mut BrightnessGrid, |     brightness_grid: NonNull<BrightnessGrid>, | ||||||
|     value: u8, |     value: u8, | ||||||
| ) { | ) { | ||||||
|     assert!(!brightness_grid.is_null()); |  | ||||||
|     let brightness = servicepoint::Brightness::try_from(value) |     let brightness = servicepoint::Brightness::try_from(value) | ||||||
|         .expect("invalid brightness value"); |         .expect("invalid brightness value"); | ||||||
|     unsafe { (*brightness_grid).fill(brightness) }; |     unsafe { (*brightness_grid.as_ptr()).fill(brightness) }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets the width of the [SPBrightnessGrid] instance.
 | /// Gets the width of the [SPBrightnessGrid] instance.
 | ||||||
|  | @ -260,10 +250,9 @@ pub unsafe extern "C" fn sp_brightness_grid_fill( | ||||||
| /// - `brightness_grid` points to a valid [SPBrightnessGrid]
 | /// - `brightness_grid` points to a valid [SPBrightnessGrid]
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_brightness_grid_width( | pub unsafe extern "C" fn sp_brightness_grid_width( | ||||||
|     brightness_grid: *const BrightnessGrid, |     brightness_grid: NonNull<BrightnessGrid>, | ||||||
| ) -> usize { | ) -> usize { | ||||||
|     assert!(!brightness_grid.is_null()); |     unsafe { brightness_grid.as_ref().width() } | ||||||
|     unsafe { (*brightness_grid).width() } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets the height of the [SPBrightnessGrid] instance.
 | /// Gets the height of the [SPBrightnessGrid] instance.
 | ||||||
|  | @ -285,10 +274,9 @@ pub unsafe extern "C" fn sp_brightness_grid_width( | ||||||
| /// - `brightness_grid` points to a valid [SPBrightnessGrid]
 | /// - `brightness_grid` points to a valid [SPBrightnessGrid]
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_brightness_grid_height( | pub unsafe extern "C" fn sp_brightness_grid_height( | ||||||
|     brightness_grid: *const BrightnessGrid, |     brightness_grid: NonNull<BrightnessGrid>, | ||||||
| ) -> usize { | ) -> usize { | ||||||
|     assert!(!brightness_grid.is_null()); |     unsafe { brightness_grid.as_ref().height() } | ||||||
|     unsafe { (*brightness_grid).height() } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets an unsafe reference to the data of the [SPBrightnessGrid] instance.
 | /// Gets an unsafe reference to the data of the [SPBrightnessGrid] instance.
 | ||||||
|  | @ -312,12 +300,10 @@ pub unsafe extern "C" fn sp_brightness_grid_height( | ||||||
| /// - the returned memory range is never accessed concurrently, either via the [SPBrightnessGrid] or directly
 | /// - the returned memory range is never accessed concurrently, either via the [SPBrightnessGrid] or directly
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_brightness_grid_unsafe_data_ref( | pub unsafe extern "C" fn sp_brightness_grid_unsafe_data_ref( | ||||||
|     brightness_grid: *mut BrightnessGrid, |     brightness_grid: NonNull<BrightnessGrid>, | ||||||
| ) -> SPByteSlice { | ) -> SPByteSlice { | ||||||
|     assert!(!brightness_grid.is_null()); |     assert_eq!(size_of::<servicepoint::Brightness>(), 1); | ||||||
|     assert_eq!(core::mem::size_of::<servicepoint::Brightness>(), 1); |     let data = unsafe { (*brightness_grid.as_ptr()).data_ref_mut() }; | ||||||
|     let data = unsafe { (*brightness_grid).data_ref_mut() }; |  | ||||||
|     // this assumes more about the memory layout than rust guarantees. yikes!
 |     // this assumes more about the memory layout than rust guarantees. yikes!
 | ||||||
|     unsafe { SPByteSlice::from_slice(transmute(data)) } |     unsafe { SPByteSlice::from_slice(transmute(data)) } | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -28,7 +28,7 @@ impl SPByteSlice { | ||||||
|         unsafe { std::slice::from_raw_parts(self.start.as_ptr(), self.length) } |         unsafe { std::slice::from_raw_parts(self.start.as_ptr(), self.length) } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub(crate) unsafe fn as_slice_mut(&mut self) -> &mut [u8] { |     pub(crate) unsafe fn as_slice_mut(&self) -> &mut [u8] { | ||||||
|         unsafe { |         unsafe { | ||||||
|             std::slice::from_raw_parts_mut(self.start.as_ptr(), self.length) |             std::slice::from_raw_parts_mut(self.start.as_ptr(), self.length) | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -18,6 +18,7 @@ | ||||||
| //! sp_char_grid_free(grid);
 | //! sp_char_grid_free(grid);
 | ||||||
| //! ```
 | //! ```
 | ||||||
| 
 | 
 | ||||||
|  | use crate::SPByteSlice; | ||||||
| use servicepoint::{CharGrid, Grid}; | use servicepoint::{CharGrid, Grid}; | ||||||
| use std::ptr::NonNull; | use std::ptr::NonNull; | ||||||
| 
 | 
 | ||||||
|  | @ -36,7 +37,7 @@ pub unsafe extern "C" fn sp_char_grid_new( | ||||||
|     width: usize, |     width: usize, | ||||||
|     height: usize, |     height: usize, | ||||||
| ) -> NonNull<CharGrid> { | ) -> NonNull<CharGrid> { | ||||||
|     let result =        Box::new(CharGrid::new(width, height)); |     let result = Box::new(CharGrid::new(width, height)); | ||||||
|     NonNull::from(Box::leak(result)) |     NonNull::from(Box::leak(result)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -62,16 +63,12 @@ pub unsafe extern "C" fn sp_char_grid_new( | ||||||
| pub unsafe extern "C" fn sp_char_grid_load( | pub unsafe extern "C" fn sp_char_grid_load( | ||||||
|     width: usize, |     width: usize, | ||||||
|     height: usize, |     height: usize, | ||||||
|     data: *const u8, |     data: SPByteSlice, | ||||||
|     data_length: usize, |  | ||||||
| ) -> NonNull<CharGrid> { | ) -> NonNull<CharGrid> { | ||||||
|     assert!(data.is_null()); |     let data = unsafe { data.as_slice() }; | ||||||
|     let data = unsafe { std::slice::from_raw_parts(data, data_length) }; |  | ||||||
|     // TODO remove unwrap
 |     // TODO remove unwrap
 | ||||||
|     let result = Box::new( |     let result = | ||||||
|         CharGrid::load_utf8(width, height, data.to_vec()) |         Box::new(CharGrid::load_utf8(width, height, data.to_vec()).unwrap()); | ||||||
|             .unwrap(), |  | ||||||
|     ); |  | ||||||
|     NonNull::from(Box::leak(result)) |     NonNull::from(Box::leak(result)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -93,10 +90,9 @@ pub unsafe extern "C" fn sp_char_grid_load( | ||||||
| ///   by explicitly calling `sp_char_grid_free`.
 | ///   by explicitly calling `sp_char_grid_free`.
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_char_grid_clone( | pub unsafe extern "C" fn sp_char_grid_clone( | ||||||
|     char_grid: *const CharGrid, |     char_grid: NonNull<CharGrid>, | ||||||
| ) -> NonNull<CharGrid> { | ) -> NonNull<CharGrid> { | ||||||
|     assert!(!char_grid.is_null()); |     let result = Box::new(unsafe { char_grid.as_ref().clone() }); | ||||||
|     let result = Box::new(unsafe { (*char_grid).clone() }); |  | ||||||
|     NonNull::from(Box::leak(result)) |     NonNull::from(Box::leak(result)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -116,9 +112,8 @@ pub unsafe extern "C" fn sp_char_grid_clone( | ||||||
| ///
 | ///
 | ||||||
| /// [SPCommand]: [crate::SPCommand]
 | /// [SPCommand]: [crate::SPCommand]
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_char_grid_free(char_grid: *mut CharGrid) { | pub unsafe extern "C" fn sp_char_grid_free(char_grid: NonNull<CharGrid>) { | ||||||
|     assert!(!char_grid.is_null()); |     _ = unsafe { Box::from_raw(char_grid.as_ptr()) }; | ||||||
|     _ = unsafe { Box::from_raw(char_grid) }; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets the current value at the specified position.
 | /// Gets the current value at the specified position.
 | ||||||
|  | @ -141,12 +136,11 @@ pub unsafe extern "C" fn sp_char_grid_free(char_grid: *mut CharGrid) { | ||||||
| /// - `char_grid` is not written to concurrently
 | /// - `char_grid` is not written to concurrently
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_char_grid_get( | pub unsafe extern "C" fn sp_char_grid_get( | ||||||
|     char_grid: *const CharGrid, |     char_grid: NonNull<CharGrid>, | ||||||
|     x: usize, |     x: usize, | ||||||
|     y: usize, |     y: usize, | ||||||
| ) -> u32 { | ) -> u32 { | ||||||
|     assert!(!char_grid.is_null()); |     unsafe { char_grid.as_ref().get(x, y) as u32 } | ||||||
|     unsafe { (*char_grid).get(x, y) as u32 } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Sets the value of the specified position in the [SPCharGrid].
 | /// Sets the value of the specified position in the [SPCharGrid].
 | ||||||
|  | @ -174,13 +168,12 @@ pub unsafe extern "C" fn sp_char_grid_get( | ||||||
| /// [SPBitVec]: [crate::SPBitVec]
 | /// [SPBitVec]: [crate::SPBitVec]
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_char_grid_set( | pub unsafe extern "C" fn sp_char_grid_set( | ||||||
|     char_grid: *mut CharGrid, |     char_grid: NonNull<CharGrid>, | ||||||
|     x: usize, |     x: usize, | ||||||
|     y: usize, |     y: usize, | ||||||
|     value: u32, |     value: u32, | ||||||
| ) { | ) { | ||||||
|     assert!(!char_grid.is_null()); |     unsafe { (*char_grid.as_ptr()).set(x, y, char::from_u32(value).unwrap()) }; | ||||||
|     unsafe { (*char_grid).set(x, y, char::from_u32(value).unwrap()) }; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Sets the value of all cells in the [SPCharGrid].
 | /// Sets the value of all cells in the [SPCharGrid].
 | ||||||
|  | @ -202,11 +195,10 @@ pub unsafe extern "C" fn sp_char_grid_set( | ||||||
| /// - `char_grid` is not written to or read from concurrently
 | /// - `char_grid` is not written to or read from concurrently
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_char_grid_fill( | pub unsafe extern "C" fn sp_char_grid_fill( | ||||||
|     char_grid: *mut CharGrid, |     char_grid: NonNull<CharGrid>, | ||||||
|     value: u32, |     value: u32, | ||||||
| ) { | ) { | ||||||
|     assert!(!char_grid.is_null()); |     unsafe { (*char_grid.as_ptr()).fill(char::from_u32(value).unwrap()) }; | ||||||
|     unsafe { (*char_grid).fill(char::from_u32(value).unwrap()) }; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets the width of the [SPCharGrid] instance.
 | /// Gets the width of the [SPCharGrid] instance.
 | ||||||
|  | @ -226,10 +218,9 @@ pub unsafe extern "C" fn sp_char_grid_fill( | ||||||
| /// - `char_grid` points to a valid [SPCharGrid]
 | /// - `char_grid` points to a valid [SPCharGrid]
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_char_grid_width( | pub unsafe extern "C" fn sp_char_grid_width( | ||||||
|     char_grid: *const CharGrid, |     char_grid: NonNull<CharGrid>, | ||||||
| ) -> usize { | ) -> usize { | ||||||
|     assert!(!char_grid.is_null()); |     unsafe { char_grid.as_ref().width() } | ||||||
|     unsafe { (*char_grid).width() } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets the height of the [SPCharGrid] instance.
 | /// Gets the height of the [SPCharGrid] instance.
 | ||||||
|  | @ -249,8 +240,7 @@ pub unsafe extern "C" fn sp_char_grid_width( | ||||||
| /// - `char_grid` points to a valid [SPCharGrid]
 | /// - `char_grid` points to a valid [SPCharGrid]
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_char_grid_height( | pub unsafe extern "C" fn sp_char_grid_height( | ||||||
|     char_grid: *const CharGrid, |     char_grid: NonNull<CharGrid>, | ||||||
| ) -> usize { | ) -> usize { | ||||||
|     assert!(!char_grid.is_null()); |     unsafe { char_grid.as_ref().height() } | ||||||
|     unsafe { (*char_grid).height() } |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -2,8 +2,11 @@ | ||||||
| //!
 | //!
 | ||||||
| //! prefix `sp_command_`
 | //! prefix `sp_command_`
 | ||||||
| 
 | 
 | ||||||
| use crate::{SPBitVec}; | use crate::SPBitVec; | ||||||
| use servicepoint::{BinaryOperation, BrightnessGrid, CharGrid, CompressionCode, Cp437Grid, GlobalBrightnessCommand, Packet, TypedCommand}; | use servicepoint::{ | ||||||
|  |     BinaryOperation, Bitmap, BrightnessGrid, CharGrid, CompressionCode, | ||||||
|  |     Cp437Grid, GlobalBrightnessCommand, Packet, TypedCommand, | ||||||
|  | }; | ||||||
| use std::ptr::NonNull; | use std::ptr::NonNull; | ||||||
| 
 | 
 | ||||||
| /// A low-level display command.
 | /// A low-level display command.
 | ||||||
|  | @ -21,7 +24,6 @@ use std::ptr::NonNull; | ||||||
| ///
 | ///
 | ||||||
| /// [SPConnection]: [crate::SPConnection]
 | /// [SPConnection]: [crate::SPConnection]
 | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| /// Tries to turn a [SPPacket] into a [SPCommand].
 | /// Tries to turn a [SPPacket] into a [SPCommand].
 | ||||||
| ///
 | ///
 | ||||||
| /// The packet is deallocated in the process.
 | /// The packet is deallocated in the process.
 | ||||||
|  | @ -43,9 +45,9 @@ use std::ptr::NonNull; | ||||||
| ///   by explicitly calling `sp_command_free`.
 | ///   by explicitly calling `sp_command_free`.
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_command_try_from_packet( | pub unsafe extern "C" fn sp_command_try_from_packet( | ||||||
|     packet: *mut Packet, |     packet: NonNull<Packet>, | ||||||
| ) -> *mut TypedCommand { | ) -> *mut TypedCommand { | ||||||
|     let packet = *unsafe { Box::from_raw(packet) }; |     let packet = *unsafe { Box::from_raw(packet.as_ptr()) }; | ||||||
|     match servicepoint::TypedCommand::try_from(packet) { |     match servicepoint::TypedCommand::try_from(packet) { | ||||||
|         Err(_) => std::ptr::null_mut(), |         Err(_) => std::ptr::null_mut(), | ||||||
|         Ok(command) => Box::into_raw(Box::new(command)), |         Ok(command) => Box::into_raw(Box::new(command)), | ||||||
|  | @ -70,10 +72,9 @@ pub unsafe extern "C" fn sp_command_try_from_packet( | ||||||
| ///   by explicitly calling `sp_command_free`.
 | ///   by explicitly calling `sp_command_free`.
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_command_clone( | pub unsafe extern "C" fn sp_command_clone( | ||||||
|     command: *const TypedCommand, |     command: NonNull<TypedCommand>, | ||||||
| ) -> NonNull<TypedCommand> { | ) -> NonNull<TypedCommand> { | ||||||
|     assert!(!command.is_null()); |     let result = Box::new(unsafe { command.as_ref().clone() }); | ||||||
|     let result = Box::new(unsafe { (*command).clone() }); |  | ||||||
|     NonNull::from(Box::leak(result)) |     NonNull::from(Box::leak(result)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -155,8 +156,7 @@ pub unsafe extern "C" fn sp_command_brightness( | ||||||
| ) -> NonNull<TypedCommand> { | ) -> NonNull<TypedCommand> { | ||||||
|     let brightness = servicepoint::Brightness::try_from(brightness) |     let brightness = servicepoint::Brightness::try_from(brightness) | ||||||
|         .expect("invalid brightness"); |         .expect("invalid brightness"); | ||||||
|     let result = |     let result = Box::new(GlobalBrightnessCommand::from(brightness).into()); | ||||||
|         Box::new(GlobalBrightnessCommand::from(brightness).into()); |  | ||||||
|     NonNull::from(Box::leak(result)) |     NonNull::from(Box::leak(result)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -182,10 +182,9 @@ pub unsafe extern "C" fn sp_command_brightness( | ||||||
| pub unsafe extern "C" fn sp_command_char_brightness( | pub unsafe extern "C" fn sp_command_char_brightness( | ||||||
|     x: usize, |     x: usize, | ||||||
|     y: usize, |     y: usize, | ||||||
|     grid: *mut BrightnessGrid, |     grid: NonNull<BrightnessGrid>, | ||||||
| ) -> NonNull<TypedCommand> { | ) -> NonNull<TypedCommand> { | ||||||
|     assert!(!grid.is_null()); |     let grid = unsafe { *Box::from_raw(grid.as_ptr()) }; | ||||||
|     let grid = unsafe { *Box::from_raw(grid) }; |  | ||||||
|     let result = Box::new( |     let result = Box::new( | ||||||
|         servicepoint::BrightnessGridCommand { |         servicepoint::BrightnessGridCommand { | ||||||
|             origin: servicepoint::Origin::new(x, y), |             origin: servicepoint::Origin::new(x, y), | ||||||
|  | @ -224,7 +223,7 @@ 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: usize, |     offset: usize, | ||||||
|     bit_vec: *mut SPBitVec, |     bit_vec: NonNull<SPBitVec>, | ||||||
|     compression: CompressionCode, |     compression: CompressionCode, | ||||||
| ) -> *mut TypedCommand { | ) -> *mut TypedCommand { | ||||||
|     unsafe { |     unsafe { | ||||||
|  | @ -265,7 +264,7 @@ 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: usize, |     offset: usize, | ||||||
|     bit_vec: *mut SPBitVec, |     bit_vec: NonNull<SPBitVec>, | ||||||
|     compression: CompressionCode, |     compression: CompressionCode, | ||||||
| ) -> *mut TypedCommand { | ) -> *mut TypedCommand { | ||||||
|     unsafe { |     unsafe { | ||||||
|  | @ -306,7 +305,7 @@ 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: usize, |     offset: usize, | ||||||
|     bit_vec: *mut SPBitVec, |     bit_vec: NonNull<SPBitVec>, | ||||||
|     compression: CompressionCode, |     compression: CompressionCode, | ||||||
| ) -> *mut TypedCommand { | ) -> *mut TypedCommand { | ||||||
|     unsafe { |     unsafe { | ||||||
|  | @ -347,7 +346,7 @@ 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: usize, |     offset: usize, | ||||||
|     bit_vec: *mut SPBitVec, |     bit_vec: NonNull<SPBitVec>, | ||||||
|     compression: CompressionCode, |     compression: CompressionCode, | ||||||
| ) -> *mut TypedCommand { | ) -> *mut TypedCommand { | ||||||
|     unsafe { |     unsafe { | ||||||
|  | @ -363,23 +362,22 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_xor( | ||||||
| #[inline] | #[inline] | ||||||
| unsafe fn sp_command_bitmap_linear_internal( | unsafe fn sp_command_bitmap_linear_internal( | ||||||
|     offset: usize, |     offset: usize, | ||||||
|     bit_vec: *mut SPBitVec, |     bit_vec: NonNull<SPBitVec>, | ||||||
|     compression: CompressionCode, |     compression: CompressionCode, | ||||||
|     operation: BinaryOperation, |     operation: BinaryOperation, | ||||||
| ) -> *mut TypedCommand { | ) -> *mut TypedCommand { | ||||||
|     assert!(!bit_vec.is_null()); |     let bit_vec = unsafe { *Box::from_raw(bit_vec.as_ptr()) }; | ||||||
|     let bit_vec = unsafe { *Box::from_raw(bit_vec) }; |  | ||||||
|     let compression = match compression.try_into() { |     let compression = match compression.try_into() { | ||||||
|         Ok(compression) => compression, |         Ok(compression) => compression, | ||||||
|         Err(_) => return std::ptr::null_mut(), |         Err(_) => return std::ptr::null_mut(), | ||||||
|     }; |     }; | ||||||
|     let command =         servicepoint::BitVecCommand { |     let command = servicepoint::BitVecCommand { | ||||||
|             offset, |         offset, | ||||||
|             operation, |         operation, | ||||||
|             bitvec: bit_vec.into(), |         bitvec: bit_vec.0, | ||||||
|             compression, |         compression, | ||||||
|         } |     } | ||||||
|         .into(); |     .into(); | ||||||
|     Box::leak(Box::new(command)) |     Box::leak(Box::new(command)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -405,10 +403,9 @@ unsafe fn sp_command_bitmap_linear_internal( | ||||||
| pub unsafe extern "C" fn sp_command_cp437_data( | pub unsafe extern "C" fn sp_command_cp437_data( | ||||||
|     x: usize, |     x: usize, | ||||||
|     y: usize, |     y: usize, | ||||||
|     grid: *mut Cp437Grid, |     grid: NonNull<Cp437Grid>, | ||||||
| ) -> NonNull<TypedCommand> { | ) -> NonNull<TypedCommand> { | ||||||
|     assert!(!grid.is_null()); |     let grid = *unsafe { Box::from_raw(grid.as_ptr()) }; | ||||||
|     let grid = *unsafe { Box::from_raw(grid) }; |  | ||||||
|     let result = Box::new( |     let result = Box::new( | ||||||
|         servicepoint::Cp437GridCommand { |         servicepoint::Cp437GridCommand { | ||||||
|             origin: servicepoint::Origin::new(x, y), |             origin: servicepoint::Origin::new(x, y), | ||||||
|  | @ -441,10 +438,9 @@ pub unsafe extern "C" fn sp_command_cp437_data( | ||||||
| pub unsafe extern "C" fn sp_command_utf8_data( | pub unsafe extern "C" fn sp_command_utf8_data( | ||||||
|     x: usize, |     x: usize, | ||||||
|     y: usize, |     y: usize, | ||||||
|     grid: *mut CharGrid, |     grid: NonNull<CharGrid>, | ||||||
| ) -> NonNull<TypedCommand> { | ) -> NonNull<TypedCommand> { | ||||||
|     assert!(!grid.is_null()); |     let grid = unsafe { *Box::from_raw(grid.as_ptr()) }; | ||||||
|     let grid = unsafe { *Box::from_raw(grid) }; |  | ||||||
|     let result = Box::new( |     let result = Box::new( | ||||||
|         servicepoint::CharGridCommand { |         servicepoint::CharGridCommand { | ||||||
|             origin: servicepoint::Origin::new(x, y), |             origin: servicepoint::Origin::new(x, y), | ||||||
|  | @ -479,21 +475,20 @@ pub unsafe extern "C" fn sp_command_utf8_data( | ||||||
| pub unsafe extern "C" fn sp_command_bitmap_linear_win( | pub unsafe extern "C" fn sp_command_bitmap_linear_win( | ||||||
|     x: usize, |     x: usize, | ||||||
|     y: usize, |     y: usize, | ||||||
|     bitmap: *mut servicepoint::Bitmap, |     bitmap: NonNull<Bitmap>, | ||||||
|     compression: CompressionCode, |     compression: CompressionCode, | ||||||
| ) -> *mut TypedCommand { | ) -> *mut TypedCommand { | ||||||
|     assert!(!bitmap.is_null()); |     let bitmap = unsafe { *Box::from_raw(bitmap.as_ptr()) }; | ||||||
|     let bitmap = unsafe { *Box::from_raw(bitmap) }; |  | ||||||
|     let compression = match compression.try_into() { |     let compression = match compression.try_into() { | ||||||
|         Ok(compression) => compression, |         Ok(compression) => compression, | ||||||
|         Err(_) => return std::ptr::null_mut(), |         Err(_) => return std::ptr::null_mut(), | ||||||
|     }; |     }; | ||||||
|     let command =         servicepoint::BitmapCommand { |     let command = servicepoint::BitmapCommand { | ||||||
|             origin: servicepoint::Origin::new(x, y), |         origin: servicepoint::Origin::new(x, y), | ||||||
|             bitmap, |         bitmap, | ||||||
|             compression, |         compression, | ||||||
|         } |     } | ||||||
|         .into(); |     .into(); | ||||||
|     Box::leak(Box::new(command)) |     Box::leak(Box::new(command)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -518,7 +513,6 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_win( | ||||||
| /// - `command` is not used concurrently or after this call
 | /// - `command` is not used concurrently or after this call
 | ||||||
| /// - `command` was not passed to another consuming function, e.g. to create a [SPPacket]
 | /// - `command` was not passed to another consuming function, e.g. to create a [SPPacket]
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_command_free(command: *mut TypedCommand) { | pub unsafe extern "C" fn sp_command_free(command: NonNull<TypedCommand>) { | ||||||
|     assert!(!command.is_null()); |     _ = unsafe { Box::from_raw(command.as_ptr()) }; | ||||||
|     _ = unsafe { Box::from_raw(command) }; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ | ||||||
| 
 | 
 | ||||||
| use servicepoint::{Connection, Packet, TypedCommand, UdpConnection}; | use servicepoint::{Connection, Packet, TypedCommand, UdpConnection}; | ||||||
| use std::ffi::{c_char, CStr}; | use std::ffi::{c_char, CStr}; | ||||||
|  | use std::ptr::NonNull; | ||||||
| 
 | 
 | ||||||
| /// Creates a new instance of [SPConnection].
 | /// Creates a new instance of [SPConnection].
 | ||||||
| ///
 | ///
 | ||||||
|  | @ -31,10 +32,9 @@ use std::ffi::{c_char, CStr}; | ||||||
| ///   by explicitly calling `sp_connection_free`.
 | ///   by explicitly calling `sp_connection_free`.
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_connection_open( | pub unsafe extern "C" fn sp_connection_open( | ||||||
|     host: *const c_char, |     host: NonNull<c_char>, | ||||||
| ) -> *mut UdpConnection { | ) -> *mut UdpConnection { | ||||||
|     assert!(!host.is_null()); |     let host = unsafe { CStr::from_ptr(host.as_ptr()) } | ||||||
|     let host = unsafe { CStr::from_ptr(host) } |  | ||||||
|         .to_str() |         .to_str() | ||||||
|         .expect("Bad encoding"); |         .expect("Bad encoding"); | ||||||
|     let connection = match UdpConnection::open(host) { |     let connection = match UdpConnection::open(host) { | ||||||
|  | @ -93,13 +93,11 @@ pub unsafe extern "C" fn sp_connection_open( | ||||||
| /// - `packet` is not used concurrently or after this call
 | /// - `packet` is not used concurrently or after this call
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_connection_send_packet( | pub unsafe extern "C" fn sp_connection_send_packet( | ||||||
|     connection: *const UdpConnection, |     connection: NonNull<UdpConnection>, | ||||||
|     packet: *mut Packet, |     packet: NonNull<Packet>, | ||||||
| ) -> bool { | ) -> bool { | ||||||
|     assert!(!connection.is_null()); |     let packet = unsafe { Box::from_raw(packet.as_ptr()) }; | ||||||
|     assert!(!packet.is_null()); |     unsafe { connection.as_ref().send(*packet) }.is_ok() | ||||||
|     let packet = unsafe { Box::from_raw(packet) }; |  | ||||||
|     unsafe { (*connection).send(*packet) }.is_ok() |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Sends a [SPCommand] to the display using the [SPConnection].
 | /// Sends a [SPCommand] to the display using the [SPConnection].
 | ||||||
|  | @ -122,13 +120,11 @@ pub unsafe extern "C" fn sp_connection_send_packet( | ||||||
| /// - `command` is not used concurrently or after this call
 | /// - `command` is not used concurrently or after this call
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_connection_send_command( | pub unsafe extern "C" fn sp_connection_send_command( | ||||||
|     connection: *const UdpConnection, |     connection: NonNull<UdpConnection>, | ||||||
|     command: *mut TypedCommand, |     command: NonNull<TypedCommand>, | ||||||
| ) -> bool { | ) -> bool { | ||||||
|     assert!(!connection.is_null()); |     let command = *unsafe { Box::from_raw(command.as_ptr()) }; | ||||||
|     assert!(!command.is_null()); |     unsafe { connection.as_ref().send(command) }.is_ok() | ||||||
|     let command = *unsafe { Box::from_raw(command) }; |  | ||||||
|     unsafe { (*connection).send(command) }.is_ok() |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Closes and deallocates a [SPConnection].
 | /// Closes and deallocates a [SPConnection].
 | ||||||
|  | @ -144,7 +140,8 @@ pub unsafe extern "C" fn sp_connection_send_command( | ||||||
| /// - `connection` points to a valid [SPConnection]
 | /// - `connection` points to a valid [SPConnection]
 | ||||||
| /// - `connection` is not used concurrently or after this call
 | /// - `connection` is not used concurrently or after this call
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_connection_free(connection: *mut UdpConnection) { | pub unsafe extern "C" fn sp_connection_free( | ||||||
|     assert!(!connection.is_null()); |     connection: NonNull<UdpConnection>, | ||||||
|     _ = unsafe { Box::from_raw(connection) }; | ) { | ||||||
|  |     _ = unsafe { Box::from_raw(connection.as_ptr()) }; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -35,7 +35,7 @@ pub unsafe extern "C" fn sp_cp437_grid_new( | ||||||
|     width: usize, |     width: usize, | ||||||
|     height: usize, |     height: usize, | ||||||
| ) -> NonNull<Cp437Grid> { | ) -> NonNull<Cp437Grid> { | ||||||
|     let result =        Box::new(Cp437Grid::new(width, height)); |     let result = Box::new(Cp437Grid::new(width, height)); | ||||||
|     NonNull::from(Box::leak(result)) |     NonNull::from(Box::leak(result)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -60,11 +60,9 @@ pub unsafe extern "C" fn sp_cp437_grid_new( | ||||||
| pub unsafe extern "C" fn sp_cp437_grid_load( | pub unsafe extern "C" fn sp_cp437_grid_load( | ||||||
|     width: usize, |     width: usize, | ||||||
|     height: usize, |     height: usize, | ||||||
|     data: *const u8, |     data: SPByteSlice, | ||||||
|     data_length: usize, |  | ||||||
| ) -> *mut Cp437Grid { | ) -> *mut Cp437Grid { | ||||||
|     assert!(data.is_null()); |     let data = unsafe { data.as_slice() }; | ||||||
|     let data = unsafe { std::slice::from_raw_parts(data, data_length) }; |  | ||||||
|     let grid = Cp437Grid::load(width, height, data); |     let grid = Cp437Grid::load(width, height, data); | ||||||
|     if let Some(grid) = grid { |     if let Some(grid) = grid { | ||||||
|         Box::leak(Box::new(grid)) |         Box::leak(Box::new(grid)) | ||||||
|  | @ -91,10 +89,9 @@ pub unsafe extern "C" fn sp_cp437_grid_load( | ||||||
| ///   by explicitly calling `sp_cp437_grid_free`.
 | ///   by explicitly calling `sp_cp437_grid_free`.
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_cp437_grid_clone( | pub unsafe extern "C" fn sp_cp437_grid_clone( | ||||||
|     cp437_grid: *const Cp437Grid, |     cp437_grid: NonNull<Cp437Grid>, | ||||||
| ) -> NonNull<Cp437Grid> { | ) -> NonNull<Cp437Grid> { | ||||||
|     assert!(!cp437_grid.is_null()); |     let result = Box::new(unsafe { cp437_grid.as_ref().clone() }); | ||||||
|     let result = Box::new(unsafe { (*cp437_grid).clone() }); |  | ||||||
|     NonNull::from(Box::leak(result)) |     NonNull::from(Box::leak(result)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -114,9 +111,8 @@ pub unsafe extern "C" fn sp_cp437_grid_clone( | ||||||
| ///
 | ///
 | ||||||
| /// [SPCommand]: [crate::SPCommand]
 | /// [SPCommand]: [crate::SPCommand]
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_cp437_grid_free(cp437_grid: *mut Cp437Grid) { | pub unsafe extern "C" fn sp_cp437_grid_free(cp437_grid: NonNull<Cp437Grid>) { | ||||||
|     assert!(!cp437_grid.is_null()); |     _ = unsafe { Box::from_raw(cp437_grid.as_ptr()) }; | ||||||
|     _ = unsafe { Box::from_raw(cp437_grid) }; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets the current value at the specified position.
 | /// Gets the current value at the specified position.
 | ||||||
|  | @ -139,12 +135,11 @@ pub unsafe extern "C" fn sp_cp437_grid_free(cp437_grid: *mut Cp437Grid) { | ||||||
| /// - `cp437_grid` is not written to concurrently
 | /// - `cp437_grid` is not written to concurrently
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_cp437_grid_get( | pub unsafe extern "C" fn sp_cp437_grid_get( | ||||||
|     cp437_grid: *const Cp437Grid, |     cp437_grid: NonNull<Cp437Grid>, | ||||||
|     x: usize, |     x: usize, | ||||||
|     y: usize, |     y: usize, | ||||||
| ) -> u8 { | ) -> u8 { | ||||||
|     assert!(!cp437_grid.is_null()); |     unsafe { cp437_grid.as_ref().get(x, y) } | ||||||
|     unsafe { (*cp437_grid).get(x, y) } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Sets the value of the specified position in the [SPCp437Grid].
 | /// Sets the value of the specified position in the [SPCp437Grid].
 | ||||||
|  | @ -172,13 +167,12 @@ pub unsafe extern "C" fn sp_cp437_grid_get( | ||||||
| /// [SPBitVec]: [crate::SPBitVec]
 | /// [SPBitVec]: [crate::SPBitVec]
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_cp437_grid_set( | pub unsafe extern "C" fn sp_cp437_grid_set( | ||||||
|     cp437_grid: *mut Cp437Grid, |     cp437_grid: NonNull<Cp437Grid>, | ||||||
|     x: usize, |     x: usize, | ||||||
|     y: usize, |     y: usize, | ||||||
|     value: u8, |     value: u8, | ||||||
| ) { | ) { | ||||||
|     assert!(!cp437_grid.is_null()); |     unsafe { (*cp437_grid.as_ptr()).set(x, y, value) }; | ||||||
|     unsafe { (*cp437_grid).set(x, y, value) }; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Sets the value of all cells in the [SPCp437Grid].
 | /// Sets the value of all cells in the [SPCp437Grid].
 | ||||||
|  | @ -200,11 +194,10 @@ pub unsafe extern "C" fn sp_cp437_grid_set( | ||||||
| /// - `cp437_grid` is not written to or read from concurrently
 | /// - `cp437_grid` is not written to or read from concurrently
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_cp437_grid_fill( | pub unsafe extern "C" fn sp_cp437_grid_fill( | ||||||
|     cp437_grid: *mut Cp437Grid, |     cp437_grid: NonNull<Cp437Grid>, | ||||||
|     value: u8, |     value: u8, | ||||||
| ) { | ) { | ||||||
|     assert!(!cp437_grid.is_null()); |     unsafe { (*cp437_grid.as_ptr()).fill(value) }; | ||||||
|     unsafe { (*cp437_grid).fill(value) }; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets the width of the [SPCp437Grid] instance.
 | /// Gets the width of the [SPCp437Grid] instance.
 | ||||||
|  | @ -224,10 +217,9 @@ pub unsafe extern "C" fn sp_cp437_grid_fill( | ||||||
| /// - `cp437_grid` points to a valid [SPCp437Grid]
 | /// - `cp437_grid` points to a valid [SPCp437Grid]
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_cp437_grid_width( | pub unsafe extern "C" fn sp_cp437_grid_width( | ||||||
|     cp437_grid: *const Cp437Grid, |     cp437_grid: NonNull<Cp437Grid>, | ||||||
| ) -> usize { | ) -> usize { | ||||||
|     assert!(!cp437_grid.is_null()); |     unsafe { cp437_grid.as_ref().width() } | ||||||
|     unsafe { (*cp437_grid).width() } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets the height of the [SPCp437Grid] instance.
 | /// Gets the height of the [SPCp437Grid] instance.
 | ||||||
|  | @ -247,10 +239,9 @@ pub unsafe extern "C" fn sp_cp437_grid_width( | ||||||
| /// - `cp437_grid` points to a valid [SPCp437Grid]
 | /// - `cp437_grid` points to a valid [SPCp437Grid]
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_cp437_grid_height( | pub unsafe extern "C" fn sp_cp437_grid_height( | ||||||
|     cp437_grid: *const Cp437Grid, |     cp437_grid: NonNull<Cp437Grid>, | ||||||
| ) -> usize { | ) -> usize { | ||||||
|     assert!(!cp437_grid.is_null()); |     unsafe { cp437_grid.as_ref().height() } | ||||||
|     unsafe { (*cp437_grid).height() } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Gets an unsafe reference to the data of the [SPCp437Grid] instance.
 | /// Gets an unsafe reference to the data of the [SPCp437Grid] instance.
 | ||||||
|  | @ -270,7 +261,7 @@ pub unsafe extern "C" fn sp_cp437_grid_height( | ||||||
| /// - the returned memory range is never accessed concurrently, either via the [SPCp437Grid] or directly
 | /// - the returned memory range is never accessed concurrently, either via the [SPCp437Grid] or directly
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_cp437_grid_unsafe_data_ref( | pub unsafe extern "C" fn sp_cp437_grid_unsafe_data_ref( | ||||||
|     cp437_grid: *mut Cp437Grid, |     cp437_grid: NonNull<Cp437Grid>, | ||||||
| ) -> SPByteSlice { | ) -> SPByteSlice { | ||||||
|     unsafe {SPByteSlice::from_slice((*cp437_grid).data_ref_mut()) } |     unsafe { SPByteSlice::from_slice((*cp437_grid.as_ptr()).data_ref_mut()) } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -45,7 +45,6 @@ mod connection; | ||||||
| mod cp437_grid; | mod cp437_grid; | ||||||
| mod packet; | mod packet; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| use std::time::Duration; | use std::time::Duration; | ||||||
| 
 | 
 | ||||||
| /// Actual hardware limit is around 28-29ms/frame. Rounded up for less dropped packets.
 | /// Actual hardware limit is around 28-29ms/frame. Rounded up for less dropped packets.
 | ||||||
|  |  | ||||||
|  | @ -28,10 +28,9 @@ use std::ptr::NonNull; | ||||||
| ///   by explicitly calling `sp_packet_free`.
 | ///   by explicitly calling `sp_packet_free`.
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_packet_from_command( | pub unsafe extern "C" fn sp_packet_from_command( | ||||||
|     command: *mut TypedCommand, |     command: NonNull<TypedCommand>, | ||||||
| ) -> *mut Packet { | ) -> *mut Packet { | ||||||
|     assert!(!command.is_null()); |     let command = unsafe { *Box::from_raw(command.as_ptr()) }; | ||||||
|     let command = unsafe { *Box::from_raw(command) }; |  | ||||||
|     if let Ok(packet) = command.try_into() { |     if let Ok(packet) = command.try_into() { | ||||||
|         Box::leak(Box::new(packet)) |         Box::leak(Box::new(packet)) | ||||||
|     } else { |     } else { | ||||||
|  | @ -56,12 +55,8 @@ pub unsafe extern "C" fn sp_packet_from_command( | ||||||
| /// - the returned [SPPacket] instance is freed in some way, either by using a consuming function or
 | /// - the returned [SPPacket] instance is freed in some way, either by using a consuming function or
 | ||||||
| ///   by explicitly calling `sp_packet_free`.
 | ///   by explicitly calling `sp_packet_free`.
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_packet_try_load( | pub unsafe extern "C" fn sp_packet_try_load(data: SPByteSlice) -> *mut Packet { | ||||||
|     data: *const u8, |     let data = unsafe { data.as_slice() }; | ||||||
|     length: usize, |  | ||||||
| ) -> *mut Packet { |  | ||||||
|     assert!(!data.is_null()); |  | ||||||
|     let data = unsafe { std::slice::from_raw_parts(data, length) }; |  | ||||||
|     match servicepoint::Packet::try_from(data) { |     match servicepoint::Packet::try_from(data) { | ||||||
|         Err(_) => std::ptr::null_mut(), |         Err(_) => std::ptr::null_mut(), | ||||||
|         Ok(packet) => Box::into_raw(Box::new(packet)), |         Ok(packet) => Box::into_raw(Box::new(packet)), | ||||||
|  | @ -95,16 +90,12 @@ pub unsafe extern "C" fn sp_packet_try_load( | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_packet_from_parts( | pub unsafe extern "C" fn sp_packet_from_parts( | ||||||
|     header: Header, |     header: Header, | ||||||
|     payload: *const u8, |     payload: *const SPByteSlice, | ||||||
|     payload_len: usize, |  | ||||||
| ) -> NonNull<Packet> { | ) -> NonNull<Packet> { | ||||||
|     assert_eq!(payload.is_null(), payload_len == 0); |  | ||||||
| 
 |  | ||||||
|     let payload = if payload.is_null() { |     let payload = if payload.is_null() { | ||||||
|         vec![] |         vec![] | ||||||
|     } else { |     } else { | ||||||
|         let payload = |         let payload = unsafe { (*payload).as_slice() }; | ||||||
|             unsafe { std::slice::from_raw_parts(payload, payload_len) }; |  | ||||||
|         Vec::from(payload) |         Vec::from(payload) | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  | @ -113,34 +104,34 @@ pub unsafe extern "C" fn sp_packet_from_parts( | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_packet_get_header(packet: *mut Packet) -> *mut Header { | pub unsafe extern "C" fn sp_packet_get_header( | ||||||
|     assert!(!packet.is_null()); |     packet: NonNull<Packet>, | ||||||
|     &mut unsafe { (*packet).header } | ) -> NonNull<Header> { | ||||||
|  |     NonNull::from(&mut unsafe { (*packet.as_ptr()).header }) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_packet_get_payload(packet: *mut Packet) -> SPByteSlice { | pub unsafe extern "C" fn sp_packet_get_payload( | ||||||
|     assert!(!packet.is_null()); |     packet: NonNull<Packet>, | ||||||
|     unsafe { SPByteSlice::from_slice(&mut *(*packet).payload) } | ) -> SPByteSlice { | ||||||
|  |     unsafe { SPByteSlice::from_slice(&mut *(*packet.as_ptr()).payload) } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_packet_set_payload(packet: *mut Packet, data: SPByteSlice) { | pub unsafe extern "C" fn sp_packet_set_payload( | ||||||
|     assert!(!packet.is_null()); |     packet: NonNull<Packet>, | ||||||
|     unsafe { |     data: SPByteSlice, | ||||||
|         (*packet).payload = data.as_slice().to_vec() | ) { | ||||||
|     } |     unsafe { (*packet.as_ptr()).payload = data.as_slice().to_vec() } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_packet_write_to( | pub unsafe extern "C" fn sp_packet_write_to( | ||||||
|     packet: *const Packet, |     packet: NonNull<Packet>, | ||||||
|     mut buffer: SPByteSlice, |     buffer: SPByteSlice, | ||||||
| ) { | ) { | ||||||
|     assert!(!packet.is_null()); |  | ||||||
| 
 |  | ||||||
|     unsafe { |     unsafe { | ||||||
|         (*packet).serialize_to(buffer.as_slice_mut()); |         packet.as_ref().serialize_to(buffer.as_slice_mut()); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -162,10 +153,9 @@ pub unsafe extern "C" fn sp_packet_write_to( | ||||||
| ///   by explicitly calling `sp_packet_free`.
 | ///   by explicitly calling `sp_packet_free`.
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_packet_clone( | pub unsafe extern "C" fn sp_packet_clone( | ||||||
|     packet: *const Packet, |     packet: NonNull<Packet>, | ||||||
| ) -> NonNull<Packet> { | ) -> NonNull<Packet> { | ||||||
|     assert!(!packet.is_null()); |     let result = Box::new(unsafe { packet.as_ref().clone() }); | ||||||
|     let result = Box::new(unsafe { (*packet).clone() }); |  | ||||||
|     NonNull::from(Box::leak(result)) |     NonNull::from(Box::leak(result)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -182,7 +172,6 @@ pub unsafe extern "C" fn sp_packet_clone( | ||||||
| /// - `packet` points to a valid [SPPacket]
 | /// - `packet` points to a valid [SPPacket]
 | ||||||
| /// - `packet` is not used concurrently or after this call
 | /// - `packet` is not used concurrently or after this call
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_packet_free(packet: *mut Packet) { | pub unsafe extern "C" fn sp_packet_free(packet: NonNull<Packet>) { | ||||||
|     assert!(!packet.is_null()); |     _ = unsafe { Box::from_raw(packet.as_ptr()) } | ||||||
|     _ = unsafe { Box::from_raw(packet) } |  | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vinzenz Schroeter
						Vinzenz Schroeter