diff --git a/README.md b/README.md index e085b1b..2f089d3 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,21 @@ You have the choice of linking statically (recommended) or dynamically. - documentation is included in the header and available [online](https://docs.rs/servicepoint_binding_c/latest/servicepoint_binding_c/) +## Safety + +Functions expect that C code honors NonNull annotations. + +Any created instances have to be freed in some way. +Pointers to those instances cannot be used anymore after that. + +Instances cannot be shared between threads and need to be locked in the using code. + +Enum values have to be used as-is. Do not pass values that are not part of the enum. + +UTF-8 or UTF-32 encoding has to be used properly. + +Brightness values provided as u8 parameters must be in range. + ## Everything else Look at the main project [README](https://git.berlin.ccc.de/servicepoint/servicepoint/src/branch/main/README.md) for diff --git a/include/servicepoint.h b/include/servicepoint.h index 07bc8f8..dbce14d 100644 --- a/include/servicepoint.h +++ b/include/servicepoint.h @@ -206,9 +206,7 @@ typedef struct ValueGrid_char ValueGrid_char; typedef struct ValueGrid_u8 ValueGrid_u8; /** - * Represents a span of memory (`&mut [u8]` ) as a struct usable by C code. - * - * You should not create an instance of this type in your C code. + * Represents a span of memory (`&mut [u8]` ) as a struct. * * # Safety * @@ -217,19 +215,17 @@ typedef struct ValueGrid_u8 ValueGrid_u8; * - accesses to the memory pointed to with `start` is never accessed outside `length` * - the lifetime of the `CByteSlice` does not outlive the memory it points to, as described in * the function returning this type. - * - an instance of this created from C is never passed to a consuming function, as the rust code - * will try to free the memory of a potentially separate allocator. */ typedef struct { /** - * The start address of the memory + * The start address of the memory. */ uint8_t */*notnull*/ start; /** - * The amount of memory in bytes + * The amount of memory in bytes. */ size_t length; -} SPByteSlice; +} ByteSlice; /** * A grid containing brightness values. @@ -345,21 +341,6 @@ extern "C" { /** * Clones a [Bitmap]. - * - * Will never return NULL. - * - * # Panics - * - * - when `bitmap` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `bitmap` points to a valid [Bitmap] - * - `bitmap` is not written to concurrently - * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_bitmap_free`. */ Bitmap */*notnull*/ sp_bitmap_clone(Bitmap */*notnull*/ bitmap); @@ -370,34 +351,11 @@ Bitmap */*notnull*/ sp_bitmap_clone(Bitmap */*notnull*/ bitmap); * * - `bitmap`: instance to write to * - `value`: the value to set all pixels to - * - * # Panics - * - * - when `bitmap` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `bitmap` points to a valid [Bitmap] - * - `bitmap` is not written to or read from concurrently */ void sp_bitmap_fill(Bitmap */*notnull*/ bitmap, bool value); /** * Deallocates a [Bitmap]. - * - * # Panics - * - * - when `bitmap` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `bitmap` points to a valid [Bitmap] - * - * [TypedCommand]: [crate::TypedCommand] */ void sp_bitmap_free(Bitmap */*notnull*/ bitmap); @@ -411,15 +369,7 @@ void sp_bitmap_free(Bitmap */*notnull*/ bitmap); * * # Panics * - * - when `bitmap` is NULL * - when accessing `x` or `y` out of bounds - * - * # Safety - * - * The caller has to make sure that: - * - * - `bitmap` points to a valid [Bitmap] - * - `bitmap` is not written to concurrently */ bool sp_bitmap_get(Bitmap */*notnull*/ bitmap, size_t x, size_t y); @@ -429,16 +379,6 @@ bool sp_bitmap_get(Bitmap */*notnull*/ bitmap, size_t x, size_t y); * # Arguments * * - `bitmap`: instance to read from - * - * # Panics - * - * - when `bitmap` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `bitmap` points to a valid [Bitmap] */ size_t sp_bitmap_height(Bitmap */*notnull*/ bitmap); @@ -451,29 +391,10 @@ size_t sp_bitmap_height(Bitmap */*notnull*/ bitmap); * - `height`: size in pixels in y-direction * * returns: [Bitmap] that contains a copy of the provided data, or NULL in case of an error. - * - * # Errors - * - * In the following cases, this function will return NULL: - * - * - when the dimensions and data size do not match exactly. - * - when the width is not dividable by 8 - * - * # Panics - * - * - when `data` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `data` points to a valid memory location of at least `data_length` bytes in size. - * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_bitmap_free`. */ Bitmap *sp_bitmap_load(size_t width, size_t height, - SPByteSlice data); + ByteSlice data); /** * Creates a new [Bitmap] with the specified dimensions. @@ -491,13 +412,6 @@ Bitmap *sp_bitmap_load(size_t width, * * - when the width is not dividable by 8 * - * # Safety - * - * The caller has to make sure that: - * - * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_bitmap_free`. - * * # Examples * * ```C @@ -507,20 +421,12 @@ Bitmap *sp_bitmap_load(size_t width, * sp_bitmap_free(grid); * ``` */ -Bitmap *sp_bitmap_new(size_t width, - size_t height); +Bitmap *sp_bitmap_new(size_t width, size_t height); /** * Creates a new [Bitmap] with a size matching the screen. * - * returns: [Bitmap] initialized to all pixels off. Will never return NULL. - * - * # Safety - * - * The caller has to make sure that: - * - * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling [sp_bitmap_free]. + * returns: [Bitmap] initialized to all pixels off. */ Bitmap */*notnull*/ sp_bitmap_new_screen_sized(void); @@ -533,38 +439,18 @@ Bitmap */*notnull*/ sp_bitmap_new_screen_sized(void); * - `x` and `y`: position of the cell * - `value`: the value to write to the cell * - * returns: old value of the cell - * * # Panics * - * - when `bitmap` is NULL * - when accessing `x` or `y` out of bounds - * - * # Safety - * - * The caller has to make sure that: - * - * - `bitmap` points to a valid [Bitmap] - * - `bitmap` is not written to or read from concurrently */ void sp_bitmap_set(Bitmap */*notnull*/ bitmap, size_t x, size_t y, bool value); /** * Gets an unsafe reference to the data of the [Bitmap] instance. * - * # Panics - * - * - when `bitmap` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `bitmap` points to a valid [Bitmap] - * - the returned memory range is never accessed after the passed [Bitmap] has been freed - * - the returned memory range is never accessed concurrently, either via the [Bitmap] or directly + * The returned memory is valid for the lifetime of the bitmap. */ -SPByteSlice sp_bitmap_unsafe_data_ref(Bitmap */*notnull*/ bitmap); +ByteSlice sp_bitmap_unsafe_data_ref(Bitmap */*notnull*/ bitmap); /** * Gets the width in pixels of the [Bitmap] instance. @@ -587,21 +473,6 @@ size_t sp_bitmap_width(Bitmap */*notnull*/ bitmap); /** * Clones a [SPBitVec]. - * - * returns: new [SPBitVec] instance. Will never return NULL. - * - * # Panics - * - * - when `bit_vec` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid [SPBitVec] - * - `bit_vec` is not written to concurrently - * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_bitvec_free`. */ SPBitVec */*notnull*/ sp_bitvec_clone(SPBitVec */*notnull*/ bit_vec); @@ -612,36 +483,11 @@ SPBitVec */*notnull*/ sp_bitvec_clone(SPBitVec */*notnull*/ bit_vec); * * - `bit_vec`: instance to write to * - `value`: the value to set all bits to - * - * # Panics - * - * - when `bit_vec` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid [SPBitVec] - * - `bit_vec` is not written to or read from concurrently */ void sp_bitvec_fill(SPBitVec */*notnull*/ bit_vec, bool value); /** * Deallocates a [SPBitVec]. - * - * # Panics - * - * - when `but_vec` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid [SPBitVec] - * - `bit_vec` is not used concurrently or after this call - * - `bit_vec` was not passed to another consuming function, e.g. to create a [TypedCommand] - * - * [TypedCommand]: [crate::TypedCommand] */ void sp_bitvec_free(SPBitVec */*notnull*/ bit_vec); @@ -657,15 +503,7 @@ void sp_bitvec_free(SPBitVec */*notnull*/ bit_vec); * * # Panics * - * - when `bit_vec` is NULL * - when accessing `index` out of bounds - * - * # Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid [SPBitVec] - * - `bit_vec` is not written to concurrently */ bool sp_bitvec_get(SPBitVec */*notnull*/ bit_vec, size_t index); @@ -675,16 +513,6 @@ bool sp_bitvec_get(SPBitVec */*notnull*/ bit_vec, size_t index); * # Arguments * * - `bit_vec`: instance to write to - * - * # Panics - * - * - when `bit_vec` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid [SPBitVec] */ bool sp_bitvec_is_empty(SPBitVec */*notnull*/ bit_vec); @@ -694,38 +522,15 @@ bool sp_bitvec_is_empty(SPBitVec */*notnull*/ bit_vec); * # Arguments * * - `bit_vec`: instance to write to - * - * # Panics - * - * - when `bit_vec` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid [SPBitVec] */ size_t sp_bitvec_len(SPBitVec */*notnull*/ bit_vec); /** * Interpret the data as a series of bits and load then into a new [SPBitVec] instance. * - * returns: [SPBitVec] instance containing data. Will never return NULL. - * - * # Panics - * - * - when `data` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `data` points to a valid memory location of at least `data_length` - * bytes in size. - * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_bitvec_free`. + * returns: [SPBitVec] instance containing data. */ -SPBitVec */*notnull*/ sp_bitvec_load(SPByteSlice data); +SPBitVec */*notnull*/ sp_bitvec_load(ByteSlice data); /** * Creates a new [SPBitVec] instance. @@ -734,18 +539,11 @@ SPBitVec */*notnull*/ sp_bitvec_load(SPByteSlice data); * * - `size`: size in bits. * - * returns: [SPBitVec] with all bits set to false. Will never return NULL. + * returns: [SPBitVec] with all bits set to false. * * # Panics * * - when `size` is not divisible by 8. - * - * # Safety - * - * The caller has to make sure that: - * - * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_bitvec_free`. */ SPBitVec */*notnull*/ sp_bitvec_new(size_t size); @@ -760,60 +558,23 @@ SPBitVec */*notnull*/ sp_bitvec_new(size_t size); * * # Panics * - * - when `bit_vec` is NULL * - when accessing `index` out of bounds - * - * # Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid [SPBitVec] - * - `bit_vec` is not written to or read from concurrently */ void sp_bitvec_set(SPBitVec */*notnull*/ bit_vec, size_t index, bool value); /** * Gets an unsafe reference to the data of the [SPBitVec] instance. * + * The returned memory is valid for the lifetime of the bitvec. + * * # Arguments * * - `bit_vec`: instance to write to - * - * # Panics - * - * - when `bit_vec` is NULL - * - * ## Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid [SPBitVec] - * - the returned memory range is never accessed after the passed [SPBitVec] has been freed - * - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly */ -SPByteSlice sp_bitvec_unsafe_data_ref(SPBitVec */*notnull*/ bit_vec); +ByteSlice sp_bitvec_unsafe_data_ref(SPBitVec */*notnull*/ bit_vec); /** * Clones a [BrightnessGrid]. - * - * # Arguments - * - * - `brightness_grid`: instance to read from - * - * returns: new [BrightnessGrid] instance. Will never return NULL. - * - * # Panics - * - * - when `brightness_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `brightness_grid` points to a valid [BrightnessGrid] - * - `brightness_grid` is not written to concurrently - * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_brightness_grid_free`. */ BrightnessGrid */*notnull*/ sp_brightness_grid_clone(BrightnessGrid */*notnull*/ brightness_grid); @@ -824,42 +585,12 @@ BrightnessGrid */*notnull*/ sp_brightness_grid_clone(BrightnessGrid */*notnull*/ * * - `brightness_grid`: instance to write to * - `value`: the value to set all cells to - * - * # Panics - * - * - when `brightness_grid` is NULL - * - When providing an invalid brightness value - * - * # Safety - * - * The caller has to make sure that: - * - * - `brightness_grid` points to a valid [BrightnessGrid] - * - `brightness_grid` is not written to or read from concurrently */ void sp_brightness_grid_fill(BrightnessGrid */*notnull*/ brightness_grid, Brightness value); /** * Deallocates a [BrightnessGrid]. - * - * # Arguments - * - * - `brightness_grid`: instance to read from - * - * # Panics - * - * - when `brightness_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `brightness_grid` points to a valid [BrightnessGrid] - * - `brightness_grid` is not used concurrently or after this call - * - `brightness_grid` was not passed to another consuming function, e.g. to create a [TypedCommand] - * - * [TypedCommand]: [crate::TypedCommand] */ void sp_brightness_grid_free(BrightnessGrid */*notnull*/ brightness_grid); @@ -874,16 +605,7 @@ void sp_brightness_grid_free(BrightnessGrid */*notnull*/ brightness_grid); * returns: value at position * * # Panics - * - * - when `brightness_grid` is NULL * - When accessing `x` or `y` out of bounds. - * - * # Safety - * - * The caller has to make sure that: - * - * - `brightness_grid` points to a valid [BrightnessGrid] - * - `brightness_grid` is not written to concurrently */ Brightness sp_brightness_grid_get(BrightnessGrid */*notnull*/ brightness_grid, size_t x, @@ -897,56 +619,38 @@ Brightness sp_brightness_grid_get(BrightnessGrid */*notnull*/ brightness_grid, * - `brightness_grid`: instance to read from * * returns: height - * - * # Panics - * - * - when `brightness_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `brightness_grid` points to a valid [BrightnessGrid] */ size_t sp_brightness_grid_height(BrightnessGrid */*notnull*/ brightness_grid); /** * Loads a [BrightnessGrid] with the specified dimensions from the provided data. * - * returns: new [BrightnessGrid] instance. Will never return NULL. - * - * # Panics - * - * - when `data` is NULL - * - when the provided `data_length` does not match `height` and `width` - * - * # Safety - * - * The caller has to make sure that: - * - * - `data` points to a valid memory location of at least `data_length` - * bytes in size. - * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_brightness_grid_free`. + * returns: new [BrightnessGrid] instance, or NULL in case of an error. */ BrightnessGrid *sp_brightness_grid_load(size_t width, size_t height, - SPByteSlice data); + ByteSlice data); /** * Creates a new [BrightnessGrid] with the specified dimensions. * - * returns: [BrightnessGrid] initialized to 0. Will never return NULL. + * returns: [BrightnessGrid] initialized to 0. * - * # Safety + * # Examples + * ```C + * UdpConnection connection = sp_connection_open("127.0.0.1:2342"); + * if (connection == NULL) + * return 1; * - * The caller has to make sure that: + * BrightnessGrid grid = sp_brightness_grid_new(2, 2); + * sp_brightness_grid_set(grid, 0, 0, 0); + * sp_brightness_grid_set(grid, 1, 1, 10); * - * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_brightness_grid_free`. + * TypedCommand command = sp_command_char_brightness(grid); + * sp_connection_free(connection); + * ``` */ -BrightnessGrid */*notnull*/ sp_brightness_grid_new(size_t width, - size_t height); +BrightnessGrid */*notnull*/ sp_brightness_grid_new(size_t width, size_t height); /** * Sets the value of the specified position in the [BrightnessGrid]. @@ -961,16 +665,7 @@ BrightnessGrid */*notnull*/ sp_brightness_grid_new(size_t width, * * # Panics * - * - when `brightness_grid` is NULL * - When accessing `x` or `y` out of bounds. - * - When providing an invalid brightness value - * - * # Safety - * - * The caller has to make sure that: - * - * - `brightness_grid` points to a valid [BrightnessGrid] - * - `brightness_grid` is not written to or read from concurrently */ void sp_brightness_grid_set(BrightnessGrid */*notnull*/ brightness_grid, size_t x, @@ -980,25 +675,15 @@ void sp_brightness_grid_set(BrightnessGrid */*notnull*/ brightness_grid, /** * Gets an unsafe reference to the data of the [BrightnessGrid] instance. * + * The returned memory is valid for the lifetime of the brightness grid. + * * # Arguments * * - `brightness_grid`: instance to read from * * returns: slice of bytes underlying the `brightness_grid`. - * - * # Panics - * - * - when `brightness_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `brightness_grid` points to a valid [BrightnessGrid] - * - the returned memory range is never accessed after the passed [BrightnessGrid] has been freed - * - the returned memory range is never accessed concurrently, either via the [BrightnessGrid] or directly */ -SPByteSlice sp_brightness_grid_unsafe_data_ref(BrightnessGrid */*notnull*/ brightness_grid); +ByteSlice sp_brightness_grid_unsafe_data_ref(BrightnessGrid */*notnull*/ brightness_grid); /** * Gets the width of the [BrightnessGrid] instance. @@ -1008,36 +693,11 @@ SPByteSlice sp_brightness_grid_unsafe_data_ref(BrightnessGrid */*notnull*/ brigh * - `brightness_grid`: instance to read from * * returns: width - * - * # Panics - * - * - when `brightness_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `brightness_grid` points to a valid [BrightnessGrid] */ size_t sp_brightness_grid_width(BrightnessGrid */*notnull*/ brightness_grid); /** * Clones a [CharGrid]. - * - * Will never return NULL. - * - * # Panics - * - * - when `char_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `char_grid` points to a valid [CharGrid] - * - `char_grid` is not written to concurrently - * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_char_grid_free`. */ CharGrid */*notnull*/ sp_char_grid_clone(CharGrid */*notnull*/ char_grid); @@ -1048,41 +708,16 @@ CharGrid */*notnull*/ sp_char_grid_clone(CharGrid */*notnull*/ char_grid); * * - `char_grid`: instance to write to * - `value`: the value to set all cells to - * - * # Panics - * - * - when `char_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `char_grid` points to a valid [CharGrid] - * - `char_grid` is not written to or read from concurrently */ void sp_char_grid_fill(CharGrid */*notnull*/ char_grid, uint32_t value); /** * Deallocates a [CharGrid]. - * - * # Panics - * - * - when `char_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `char_grid` points to a valid [CharGrid] - * - `char_grid` is not used concurrently or after char_grid call - * - `char_grid` was not passed to another consuming function, e.g. to create a [TypedCommand] - * - * [TypedCommand]: [crate::TypedCommand] */ void sp_char_grid_free(CharGrid */*notnull*/ char_grid); /** - * Gets the current value at the specified position. + * Returns the current value at the specified position. * * # Arguments * @@ -1091,15 +726,7 @@ void sp_char_grid_free(CharGrid */*notnull*/ char_grid); * * # Panics * - * - when `char_grid` is NULL * - when accessing `x` or `y` out of bounds - * - * # Safety - * - * The caller has to make sure that: - * - * - `char_grid` points to a valid [CharGrid] - * - `char_grid` is not written to concurrently */ uint32_t sp_char_grid_get(CharGrid */*notnull*/ char_grid, size_t x, size_t y); @@ -1109,57 +736,31 @@ uint32_t sp_char_grid_get(CharGrid */*notnull*/ char_grid, size_t x, size_t y); * # Arguments * * - `char_grid`: instance to read from - * - * # Panics - * - * - when `char_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `char_grid` points to a valid [CharGrid] */ size_t sp_char_grid_height(CharGrid */*notnull*/ char_grid); /** * Loads a [CharGrid] with the specified dimensions from the provided data. * - * Will never return NULL. - * - * # Panics - * - * - when `data` is NULL - * - when the provided `data_length` does not match `height` and `width` - * - when `data` is not valid UTF-8 - * - * # Safety - * - * The caller has to make sure that: - * - * - `data` points to a valid memory location of at least `data_length` - * bytes in size. - * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_char_grid_free`. + * returns: new CharGrid or NULL in case of an error */ -CharGrid */*notnull*/ sp_char_grid_load(size_t width, - size_t height, - SPByteSlice data); +CharGrid *sp_char_grid_load(size_t width, size_t height, ByteSlice data); /** * Creates a new [CharGrid] with the specified dimensions. * - * returns: [CharGrid] initialized to 0. Will never return NULL. + * returns: [CharGrid] initialized to 0. * - * # Safety + * # Examples * - * The caller has to make sure that: - * - * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_char_grid_free`. + * ```C + * CharGrid grid = sp_char_grid_new(4, 3); + * sp_char_grid_fill(grid, '?'); + * sp_char_grid_set(grid, 0, 0, '!'); + * sp_char_grid_free(grid); + * ``` */ -CharGrid */*notnull*/ sp_char_grid_new(size_t width, - size_t height); +CharGrid */*notnull*/ sp_char_grid_new(size_t width, size_t height); /** * Sets the value of the specified position in the [CharGrid]. @@ -1174,17 +775,7 @@ CharGrid */*notnull*/ sp_char_grid_new(size_t width, * * # Panics * - * - when `char_grid` is NULL * - when accessing `x` or `y` out of bounds - * - * # Safety - * - * The caller has to make sure that: - * - * - `char_grid` points to a valid [SPBitVec] - * - `char_grid` is not written to or read from concurrently - * - * [SPBitVec]: [crate::SPBitVec] */ void sp_char_grid_set(CharGrid */*notnull*/ char_grid, size_t x, @@ -1197,16 +788,6 @@ void sp_char_grid_set(CharGrid */*notnull*/ char_grid, * # Arguments * * - `char_grid`: instance to read from - * - * # Panics - * - * - when `char_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `char_grid` points to a valid [CharGrid] */ size_t sp_char_grid_width(CharGrid */*notnull*/ char_grid); @@ -1220,22 +801,7 @@ size_t sp_char_grid_width(CharGrid */*notnull*/ char_grid); * * The passed [SPBitVec] gets consumed. * - * Returns: a new [servicepoint::Command::BitmapLinear] instance. Will never return NULL. - * - * # Panics - * - * - when `bit_vec` is null - * - when `compression_code` is not a valid value - * - * # Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid instance of [SPBitVec] - * - `bit_vec` is not used concurrently or after this call - * - `compression` matches one of the allowed enum values - * - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_command_free`. + * Returns: a new [servicepoint::Command::BitmapLinear] instance. */ TypedCommand *sp_command_bitmap_linear(size_t offset, SPBitVec */*notnull*/ bit_vec, @@ -1251,22 +817,7 @@ TypedCommand *sp_command_bitmap_linear(size_t offset, * * The passed [SPBitVec] gets consumed. * - * Returns: a new [servicepoint::Command::BitmapLinearAnd] instance. Will never return NULL. - * - * # Panics - * - * - when `bit_vec` is null - * - when `compression_code` is not a valid value - * - * # Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid instance of [SPBitVec] - * - `bit_vec` is not used concurrently or after this call - * - `compression` matches one of the allowed enum values - * - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_command_free`. + * Returns: a new [servicepoint::Command::BitmapLinearAnd] instance. */ TypedCommand *sp_command_bitmap_linear_and(size_t offset, SPBitVec */*notnull*/ bit_vec, @@ -1282,22 +833,7 @@ TypedCommand *sp_command_bitmap_linear_and(size_t offset, * * The passed [SPBitVec] gets consumed. * - * Returns: a new [servicepoint::Command::BitmapLinearOr] instance. Will never return NULL. - * - * # Panics - * - * - when `bit_vec` is null - * - when `compression_code` is not a valid value - * - * # Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid instance of [SPBitVec] - * - `bit_vec` is not used concurrently or after this call - * - `compression` matches one of the allowed enum values - * - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_command_free`. + * Returns: a new [servicepoint::Command::BitmapLinearOr] instance. */ TypedCommand *sp_command_bitmap_linear_or(size_t offset, SPBitVec */*notnull*/ bit_vec, @@ -1308,22 +844,7 @@ TypedCommand *sp_command_bitmap_linear_or(size_t offset, * * The passed [Bitmap] gets consumed. * - * Returns: a new [servicepoint::Command::BitmapLinearWin] instance. Will never return NULL. - * - * # Panics - * - * - when `bitmap` is null - * - when `compression_code` is not a valid value - * - * # Safety - * - * The caller has to make sure that: - * - * - `bitmap` points to a valid instance of [Bitmap] - * - `bitmap` is not used concurrently or after this call - * - `compression` matches one of the allowed enum values - * - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_command_free`. + * Returns: a new [servicepoint::Command::BitmapLinearWin] instance. */ TypedCommand *sp_command_bitmap_linear_win(size_t x, size_t y, @@ -1340,22 +861,7 @@ TypedCommand *sp_command_bitmap_linear_win(size_t x, * * The passed [SPBitVec] gets consumed. * - * Returns: a new [servicepoint::Command::BitmapLinearXor] instance. Will never return NULL. - * - * # Panics - * - * - when `bit_vec` is null - * - when `compression_code` is not a valid value - * - * # Safety - * - * The caller has to make sure that: - * - * - `bit_vec` points to a valid instance of [SPBitVec] - * - `bit_vec` is not used concurrently or after this call - * - `compression` matches one of the allowed enum values - * - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_command_free`. + * Returns: a new [servicepoint::Command::BitmapLinearXor] instance. */ TypedCommand *sp_command_bitmap_linear_xor(size_t offset, SPBitVec */*notnull*/ bit_vec, @@ -1364,18 +870,7 @@ TypedCommand *sp_command_bitmap_linear_xor(size_t offset, /** * Set the brightness of all tiles to the same value. * - * Returns: a new [servicepoint::Command::Brightness] instance. Will never return NULL. - * - * # Panics - * - * - When the provided brightness value is out of range (0-11). - * - * # Safety - * - * The caller has to make sure that: - * - * - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_command_free`. + * Returns: a new [servicepoint::Command::Brightness] instance. */ TypedCommand */*notnull*/ sp_command_brightness(Brightness brightness); @@ -1384,20 +879,7 @@ TypedCommand */*notnull*/ sp_command_brightness(Brightness brightness); * * The passed [BrightnessGrid] gets consumed. * - * Returns: a new [servicepoint::Command::CharBrightness] instance. Will never return NULL. - * - * # Panics - * - * - when `grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `grid` points to a valid instance of [BrightnessGrid] - * - `grid` is not used concurrently or after this call - * - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_command_free`. + * Returns: a new [servicepoint::Command::CharBrightness] instance. */ TypedCommand */*notnull*/ sp_command_char_brightness(size_t x, size_t y, @@ -1408,40 +890,20 @@ TypedCommand */*notnull*/ sp_command_char_brightness(size_t x, * * Does not affect brightness. * - * Returns: a new [servicepoint::Command::Clear] instance. Will never return NULL. + * Returns: a new [servicepoint::Command::Clear] instance. * * # Examples * * ```C * sp_connection_send_command(connection, sp_command_clear()); * ``` - * - * # Safety - * - * The caller has to make sure that: - * - * - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_command_free`. */ TypedCommand */*notnull*/ sp_command_clear(void); /** * Clones a [TypedCommand] instance. * - * returns: new [TypedCommand] instance. Will never return NULL. - * - * # Panics - * - * - when `command` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `command` points to a valid instance of [TypedCommand] - * - `command` is not written to concurrently - * - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_command_free`. + * returns: new [TypedCommand] instance. */ TypedCommand */*notnull*/ sp_command_clone(TypedCommand */*notnull*/ command); @@ -1450,20 +912,7 @@ TypedCommand */*notnull*/ sp_command_clone(TypedCommand */*notnull*/ command); * * The passed [Cp437Grid] gets consumed. * - * Returns: a new [servicepoint::Command::Cp437Data] instance. Will never return NULL. - * - * # Panics - * - * - when `grid` is null - * - * # Safety - * - * The caller has to make sure that: - * - * - `grid` points to a valid instance of [Cp437Grid] - * - `grid` is not used concurrently or after this call - * - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_command_free`. + * Returns: a new [servicepoint::Command::Cp437Data] instance. */ TypedCommand */*notnull*/ sp_command_cp437_data(size_t x, size_t y, @@ -1472,14 +921,7 @@ TypedCommand */*notnull*/ sp_command_cp437_data(size_t x, /** * A yet-to-be-tested command. * - * Returns: a new [servicepoint::Command::FadeOut] instance. Will never return NULL. - * - * # Safety - * - * The caller has to make sure that: - * - * - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_command_free`. + * Returns: a new [servicepoint::Command::FadeOut] instance. */ TypedCommand */*notnull*/ sp_command_fade_out(void); @@ -1492,18 +934,6 @@ TypedCommand */*notnull*/ sp_command_fade_out(void); * TypedCommand c = sp_command_clear(); * sp_command_free(c); * ``` - * - * # Panics - * - * - when `command` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `command` points to a valid [TypedCommand] - * - `command` is not used concurrently or after this call - * - `command` was not passed to another consuming function, e.g. to create a [Packet] */ void sp_command_free(TypedCommand */*notnull*/ command); @@ -1512,49 +942,16 @@ void sp_command_free(TypedCommand */*notnull*/ command); * * Please do not send this in your normal program flow. * - * Returns: a new [servicepoint::Command::HardReset] instance. Will never return NULL. - * - * # Safety - * - * The caller has to make sure that: - * - * - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_command_free`. + * Returns: a new [servicepoint::Command::HardReset] instance. */ TypedCommand */*notnull*/ sp_command_hard_reset(void); /** - * A low-level display command. - * - * This struct and associated functions implement the UDP protocol for the display. - * - * To send a [TypedCommand], use a [UdpConnection]. - * - * # Examples - * - * ```C - * sp_connection_send_command(connection, sp_command_clear()); - * sp_connection_send_command(connection, sp_command_brightness(5)); - * ``` * Tries to turn a [Packet] into a [TypedCommand]. * * The packet is deallocated in the process. * * Returns: pointer to new [TypedCommand] instance or NULL if parsing failed. - * - * # Panics - * - * - when `packet` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - [Packet] points to a valid instance of [Packet] - * - [Packet] is not used concurrently or after this call - * - the result is checked for NULL - * - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_command_free`. */ TypedCommand *sp_command_try_from_packet(Packet */*notnull*/ packet); @@ -1563,20 +960,7 @@ TypedCommand *sp_command_try_from_packet(Packet */*notnull*/ packet); * * The passed [CharGrid] gets consumed. * - * Returns: a new [servicepoint::Command::Utf8Data] instance. Will never return NULL. - * - * # Panics - * - * - when `grid` is null - * - * # Safety - * - * The caller has to make sure that: - * - * - `grid` points to a valid instance of [CharGrid] - * - `grid` is not used concurrently or after this call - * - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_command_free`. + * Returns: a new [servicepoint::Command::Utf8Data] instance. */ TypedCommand */*notnull*/ sp_command_utf8_data(size_t x, size_t y, @@ -1584,17 +968,6 @@ TypedCommand */*notnull*/ sp_command_utf8_data(size_t x, /** * Closes and deallocates a [UdpConnection]. - * - * # Panics - * - * - when `connection` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `connection` points to a valid [UdpConnection] - * - `connection` is not used concurrently or after this call */ void sp_connection_free(UdpConnection */*notnull*/ connection); @@ -1603,16 +976,13 @@ void sp_connection_free(UdpConnection */*notnull*/ connection); * * returns: NULL if connection fails, or connected instance * - * # Panics + * # Examples * - * - when `host` is null or an invalid host - * - * # Safety - * - * The caller has to make sure that: - * - * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_connection_free`. + * ```C + * CConnection connection = sp_connection_open("172.23.42.29:2342"); + * if (connection != NULL) + * sp_connection_send_command(connection, sp_command_clear()); + * ``` */ UdpConnection *sp_connection_open(char */*notnull*/ host); @@ -1623,18 +993,12 @@ UdpConnection *sp_connection_open(char */*notnull*/ host); * * returns: true in case of success * - * # Panics + * # Examples * - * - when `connection` is NULL - * - when `command` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `connection` points to a valid instance of [UdpConnection] - * - `command` points to a valid instance of [Packet] - * - `command` is not used concurrently or after this call + * ```C + * sp_connection_send_command(connection, sp_command_clear()); + * sp_connection_send_command(connection, sp_command_brightness(5)); + * ``` */ bool sp_connection_send_command(UdpConnection */*notnull*/ connection, TypedCommand */*notnull*/ command); @@ -1645,40 +1009,12 @@ bool sp_connection_send_command(UdpConnection */*notnull*/ connection, * The passed `packet` gets consumed. * * returns: true in case of success - * - * # Panics - * - * - when `connection` is NULL - * - when `packet` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `connection` points to a valid instance of [UdpConnection] - * - `packet` points to a valid instance of [Packet] - * - `packet` is not used concurrently or after this call */ bool sp_connection_send_packet(UdpConnection */*notnull*/ connection, Packet */*notnull*/ packet); /** * Clones a [Cp437Grid]. - * - * Will never return NULL. - * - * # Panics - * - * - when `cp437_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `cp437_grid` points to a valid [Cp437Grid] - * - `cp437_grid` is not written to concurrently - * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_cp437_grid_free`. */ Cp437Grid */*notnull*/ sp_cp437_grid_clone(Cp437Grid */*notnull*/ cp437_grid); @@ -1689,36 +1025,11 @@ Cp437Grid */*notnull*/ sp_cp437_grid_clone(Cp437Grid */*notnull*/ cp437_grid); * * - `cp437_grid`: instance to write to * - `value`: the value to set all cells to - * - * # Panics - * - * - when `cp437_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `cp437_grid` points to a valid [Cp437Grid] - * - `cp437_grid` is not written to or read from concurrently */ void sp_cp437_grid_fill(Cp437Grid */*notnull*/ cp437_grid, uint8_t value); /** * Deallocates a [Cp437Grid]. - * - * # Panics - * - * - when `cp437_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `cp437_grid` points to a valid [Cp437Grid] - * - `cp437_grid` is not used concurrently or after cp437_grid call - * - `cp437_grid` was not passed to another consuming function, e.g. to create a [TypedCommand] - * - * [TypedCommand]: [crate::TypedCommand] */ void sp_cp437_grid_free(Cp437Grid */*notnull*/ cp437_grid); @@ -1732,15 +1043,7 @@ void sp_cp437_grid_free(Cp437Grid */*notnull*/ cp437_grid); * * # Panics * - * - when `cp437_grid` is NULL * - when accessing `x` or `y` out of bounds - * - * # Safety - * - * The caller has to make sure that: - * - * - `cp437_grid` points to a valid [Cp437Grid] - * - `cp437_grid` is not written to concurrently */ uint8_t sp_cp437_grid_get(Cp437Grid */*notnull*/ cp437_grid, size_t x, @@ -1752,56 +1055,20 @@ uint8_t sp_cp437_grid_get(Cp437Grid */*notnull*/ cp437_grid, * # Arguments * * - `cp437_grid`: instance to read from - * - * # Panics - * - * - when `cp437_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `cp437_grid` points to a valid [Cp437Grid] */ size_t sp_cp437_grid_height(Cp437Grid */*notnull*/ cp437_grid); /** * Loads a [Cp437Grid] with the specified dimensions from the provided data. - * - * Will never return NULL. - * - * # Panics - * - * - when `data` is NULL - * - when the provided `data_length` does not match `height` and `width` - * - * # Safety - * - * The caller has to make sure that: - * - * - `data` points to a valid memory location of at least `data_length` - * bytes in size. - * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_cp437_grid_free`. */ -Cp437Grid *sp_cp437_grid_load(size_t width, - size_t height, - SPByteSlice data); +Cp437Grid *sp_cp437_grid_load(size_t width, size_t height, ByteSlice data); /** * Creates a new [Cp437Grid] with the specified dimensions. * - * returns: [Cp437Grid] initialized to 0. Will never return NULL. - * - * # Safety - * - * The caller has to make sure that: - * - * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_cp437_grid_free`. + * returns: [Cp437Grid] initialized to 0. */ -Cp437Grid */*notnull*/ sp_cp437_grid_new(size_t width, - size_t height); +Cp437Grid */*notnull*/ sp_cp437_grid_new(size_t width, size_t height); /** * Sets the value of the specified position in the [Cp437Grid]. @@ -1816,17 +1083,7 @@ Cp437Grid */*notnull*/ sp_cp437_grid_new(size_t width, * * # Panics * - * - when `cp437_grid` is NULL * - when accessing `x` or `y` out of bounds - * - * # Safety - * - * The caller has to make sure that: - * - * - `cp437_grid` points to a valid [SPBitVec] - * - `cp437_grid` is not written to or read from concurrently - * - * [SPBitVec]: [crate::SPBitVec] */ void sp_cp437_grid_set(Cp437Grid */*notnull*/ cp437_grid, size_t x, @@ -1836,21 +1093,9 @@ void sp_cp437_grid_set(Cp437Grid */*notnull*/ cp437_grid, /** * Gets an unsafe reference to the data of the [Cp437Grid] instance. * - * Will never return NULL. - * - * # Panics - * - * - when `cp437_grid` is NULL - * - * ## Safety - * - * The caller has to make sure that: - * - * - `cp437_grid` points to a valid [Cp437Grid] - * - the returned memory range is never accessed after the passed [Cp437Grid] has been freed - * - the returned memory range is never accessed concurrently, either via the [Cp437Grid] or directly + * The returned memory is valid for the lifetime of the grid. */ -SPByteSlice sp_cp437_grid_unsafe_data_ref(Cp437Grid */*notnull*/ cp437_grid); +ByteSlice sp_cp437_grid_unsafe_data_ref(Cp437Grid */*notnull*/ cp437_grid); /** * Gets the width of the [Cp437Grid] instance. @@ -1858,52 +1103,16 @@ SPByteSlice sp_cp437_grid_unsafe_data_ref(Cp437Grid */*notnull*/ cp437_grid); * # Arguments * * - `cp437_grid`: instance to read from - * - * # Panics - * - * - when `cp437_grid` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `cp437_grid` points to a valid [Cp437Grid] */ size_t sp_cp437_grid_width(Cp437Grid */*notnull*/ cp437_grid); /** * Clones a [Packet]. - * - * Will never return NULL. - * - * # Panics - * - * - when `packet` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `packet` points to a valid [Packet] - * - `packet` is not written to concurrently - * - the returned instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_packet_free`. */ Packet */*notnull*/ sp_packet_clone(Packet */*notnull*/ packet); /** * Deallocates a [Packet]. - * - * # Panics - * - * - when `packet` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `packet` points to a valid [Packet] - * - `packet` is not used concurrently or after this call */ void sp_packet_free(Packet */*notnull*/ packet); @@ -1912,50 +1121,16 @@ void sp_packet_free(Packet */*notnull*/ packet); * The [TypedCommand] gets consumed. * * Returns NULL in case of an error. - * - * # Panics - * - * - when `command` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - [TypedCommand] points to a valid instance of [TypedCommand] - * - [TypedCommand] is not used concurrently or after this call - * - the returned [Packet] instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_packet_free`. */ Packet *sp_packet_from_command(TypedCommand */*notnull*/ command); /** * Creates a raw [Packet] from parts. * - * # Arguments - * - * - `command_code` specifies which command this packet contains - * - `a`, `b`, `c` and `d` are command-specific header values - * - `payload` is the optional data that is part of the command - * - `payload_len` is the size of the payload - * * returns: new instance. Will never return null. - * - * # Panics - * - * - when `payload` is null, but `payload_len` is not zero - * - when `payload_len` is zero, but `payload` is nonnull - * - * # Safety - * - * The caller has to make sure that: - * - * - `payload` points to a valid memory region of at least `payload_len` bytes - * - `payload` is not written to concurrently - * - the returned [Packet] instance is freed in some way, either by using a consuming function or - * by explicitly calling [sp_packet_free]. */ Packet */*notnull*/ sp_packet_from_parts(Header header, - const SPByteSlice *payload); + const ByteSlice *payload); /** * Returns a pointer to the header field of the provided packet. @@ -1969,7 +1144,7 @@ Header */*notnull*/ sp_packet_get_header(Packet */*notnull*/ packet); * * The returned memory can be changed and will be valid until a new payload is set. */ -SPByteSlice sp_packet_get_payload(Packet */*notnull*/ packet); +ByteSlice sp_packet_get_payload(Packet */*notnull*/ packet); /** * Serialize the packet into the provided buffer. @@ -1978,34 +1153,21 @@ SPByteSlice sp_packet_get_payload(Packet */*notnull*/ packet); * * - if the buffer is not big enough to hold header+payload. */ -void sp_packet_serialize_to(Packet */*notnull*/ packet, SPByteSlice buffer); +void sp_packet_serialize_to(Packet */*notnull*/ packet, ByteSlice buffer); /** * Sets the payload of the provided packet to the provided data. * * This makes previous payload pointers invalid. */ -void sp_packet_set_payload(Packet */*notnull*/ packet, SPByteSlice data); +void sp_packet_set_payload(Packet */*notnull*/ packet, ByteSlice data); /** * Tries to load a [Packet] from the passed array with the specified length. * * returns: NULL in case of an error, pointer to the allocated packet otherwise - * - * # Panics - * - * - when `data` is NULL - * - * # Safety - * - * The caller has to make sure that: - * - * - `data` points to a valid memory region of at least `length` bytes - * - `data` is not written to concurrently - * - the returned [Packet] instance is freed in some way, either by using a consuming function or - * by explicitly calling `sp_packet_free`. */ -Packet *sp_packet_try_load(SPByteSlice data); +Packet *sp_packet_try_load(ByteSlice data); #ifdef __cplusplus } // extern "C" diff --git a/src/bitmap.rs b/src/bitmap.rs index 5da6e7e..f9b6882 100644 --- a/src/bitmap.rs +++ b/src/bitmap.rs @@ -1,7 +1,7 @@ use servicepoint::{Bitmap, DataRef, Grid}; use std::ptr::NonNull; -use crate::byte_slice::SPByteSlice; +use crate::byte_slice::ByteSlice; /// Creates a new [Bitmap] with the specified dimensions. /// @@ -18,13 +18,6 @@ use crate::byte_slice::SPByteSlice; /// /// - when the width is not dividable by 8 /// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - the returned instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_bitmap_free`. -/// /// # Examples /// /// ```C @@ -47,14 +40,7 @@ pub unsafe extern "C" fn sp_bitmap_new( /// Creates a new [Bitmap] with a size matching the screen. /// -/// returns: [Bitmap] initialized to all pixels off. Will never return NULL. -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - the returned instance is freed in some way, either by using a consuming function or -/// by explicitly calling [sp_bitmap_free]. +/// returns: [Bitmap] initialized to all pixels off. #[no_mangle] pub unsafe extern "C" fn sp_bitmap_new_screen_sized() -> NonNull { let result = Box::new(Bitmap::max_sized()); @@ -69,30 +55,11 @@ pub unsafe extern "C" fn sp_bitmap_new_screen_sized() -> NonNull { /// - `height`: size in pixels in y-direction /// /// returns: [Bitmap] that contains a copy of the provided data, or NULL in case of an error. -/// -/// # Errors -/// -/// In the following cases, this function will return NULL: -/// -/// - when the dimensions and data size do not match exactly. -/// - when the width is not dividable by 8 -/// -/// # Panics -/// -/// - when `data` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `data` points to a valid memory location of at least `data_length` bytes in size. -/// - the returned instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_bitmap_free`. #[no_mangle] pub unsafe extern "C" fn sp_bitmap_load( width: usize, height: usize, - data: SPByteSlice, + data: ByteSlice, ) -> *mut Bitmap { let data = unsafe { data.as_slice() }; if let Ok(bitmap) = Bitmap::load(width, height, data) { @@ -103,21 +70,6 @@ pub unsafe extern "C" fn sp_bitmap_load( } /// Clones a [Bitmap]. -/// -/// Will never return NULL. -/// -/// # Panics -/// -/// - when `bitmap` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `bitmap` points to a valid [Bitmap] -/// - `bitmap` is not written to concurrently -/// - the returned instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_bitmap_free`. #[no_mangle] pub unsafe extern "C" fn sp_bitmap_clone( bitmap: NonNull, @@ -127,18 +79,6 @@ pub unsafe extern "C" fn sp_bitmap_clone( } /// Deallocates a [Bitmap]. -/// -/// # Panics -/// -/// - when `bitmap` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `bitmap` points to a valid [Bitmap] -/// -/// [TypedCommand]: [crate::TypedCommand] #[no_mangle] pub unsafe extern "C" fn sp_bitmap_free(bitmap: NonNull) { _ = unsafe { Box::from_raw(bitmap.as_ptr()) }; @@ -153,15 +93,7 @@ pub unsafe extern "C" fn sp_bitmap_free(bitmap: NonNull) { /// /// # Panics /// -/// - when `bitmap` is NULL /// - when accessing `x` or `y` out of bounds -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `bitmap` points to a valid [Bitmap] -/// - `bitmap` is not written to concurrently #[no_mangle] pub unsafe extern "C" fn sp_bitmap_get( bitmap: NonNull, @@ -179,19 +111,9 @@ pub unsafe extern "C" fn sp_bitmap_get( /// - `x` and `y`: position of the cell /// - `value`: the value to write to the cell /// -/// returns: old value of the cell -/// /// # Panics /// -/// - when `bitmap` is NULL /// - when accessing `x` or `y` out of bounds -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `bitmap` points to a valid [Bitmap] -/// - `bitmap` is not written to or read from concurrently #[no_mangle] pub unsafe extern "C" fn sp_bitmap_set( bitmap: NonNull, @@ -208,17 +130,6 @@ pub unsafe extern "C" fn sp_bitmap_set( /// /// - `bitmap`: instance to write to /// - `value`: the value to set all pixels to -/// -/// # Panics -/// -/// - when `bitmap` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `bitmap` points to a valid [Bitmap] -/// - `bitmap` is not written to or read from concurrently #[no_mangle] pub unsafe extern "C" fn sp_bitmap_fill(bitmap: NonNull, value: bool) { unsafe { (*bitmap.as_ptr()).fill(value) }; @@ -249,16 +160,6 @@ pub unsafe extern "C" fn sp_bitmap_width(bitmap: NonNull) -> usize { /// # Arguments /// /// - `bitmap`: instance to read from -/// -/// # Panics -/// -/// - when `bitmap` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `bitmap` points to a valid [Bitmap] #[no_mangle] pub unsafe extern "C" fn sp_bitmap_height(bitmap: NonNull) -> usize { unsafe { bitmap.as_ref().height() } @@ -266,20 +167,10 @@ pub unsafe extern "C" fn sp_bitmap_height(bitmap: NonNull) -> usize { /// Gets an unsafe reference to the data of the [Bitmap] instance. /// -/// # Panics -/// -/// - when `bitmap` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `bitmap` points to a valid [Bitmap] -/// - the returned memory range is never accessed after the passed [Bitmap] has been freed -/// - the returned memory range is never accessed concurrently, either via the [Bitmap] or directly +/// The returned memory is valid for the lifetime of the bitmap. #[no_mangle] pub unsafe extern "C" fn sp_bitmap_unsafe_data_ref( mut bitmap: NonNull, -) -> SPByteSlice { - unsafe { SPByteSlice::from_slice(bitmap.as_mut().data_ref_mut()) } +) -> ByteSlice { + unsafe { ByteSlice::from_slice(bitmap.as_mut().data_ref_mut()) } } diff --git a/src/bitvec.rs b/src/bitvec.rs index a2ff022..f87423d 100644 --- a/src/bitvec.rs +++ b/src/bitvec.rs @@ -1,9 +1,6 @@ -//! C functions for interacting with [SPBitVec]s -//! -//! prefix `sp_bitvec_` - -use crate::SPByteSlice; +use crate::ByteSlice; use std::ptr::NonNull; +use servicepoint::BitVecU8Msb0; /// A vector of bits /// @@ -13,7 +10,7 @@ use std::ptr::NonNull; /// sp_bitvec_set(vec, 5, true); /// sp_bitvec_free(vec); /// ``` -pub struct SPBitVec(pub(crate) servicepoint::BitVecU8Msb0); +pub struct SPBitVec(pub(crate) BitVecU8Msb0); impl Clone for SPBitVec { fn clone(&self) -> Self { @@ -27,67 +24,31 @@ impl Clone for SPBitVec { /// /// - `size`: size in bits. /// -/// returns: [SPBitVec] with all bits set to false. Will never return NULL. +/// returns: [SPBitVec] with all bits set to false. /// /// # Panics /// /// - when `size` is not divisible by 8. -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - the returned instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_bitvec_free`. #[no_mangle] pub unsafe extern "C" fn sp_bitvec_new(size: usize) -> NonNull { let result = - Box::new(SPBitVec(servicepoint::BitVecU8Msb0::repeat(false, size))); + Box::new(SPBitVec(BitVecU8Msb0::repeat(false, size))); NonNull::from(Box::leak(result)) } /// Interpret the data as a series of bits and load then into a new [SPBitVec] instance. /// -/// returns: [SPBitVec] instance containing data. Will never return NULL. -/// -/// # Panics -/// -/// - when `data` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `data` points to a valid memory location of at least `data_length` -/// bytes in size. -/// - the returned instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_bitvec_free`. +/// returns: [SPBitVec] instance containing data. #[no_mangle] pub unsafe extern "C" fn sp_bitvec_load( - data: SPByteSlice, + data: ByteSlice, ) -> NonNull { let data = unsafe { data.as_slice() }; - let result = - Box::new(SPBitVec(servicepoint::BitVecU8Msb0::from_slice(data))); + let result = Box::new(SPBitVec(BitVecU8Msb0::from_slice(data))); NonNull::from(Box::leak(result)) } /// Clones a [SPBitVec]. -/// -/// returns: new [SPBitVec] instance. Will never return NULL. -/// -/// # Panics -/// -/// - when `bit_vec` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `bit_vec` points to a valid [SPBitVec] -/// - `bit_vec` is not written to concurrently -/// - the returned instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_bitvec_free`. #[no_mangle] pub unsafe extern "C" fn sp_bitvec_clone( bit_vec: NonNull, @@ -97,20 +58,6 @@ pub unsafe extern "C" fn sp_bitvec_clone( } /// Deallocates a [SPBitVec]. -/// -/// # Panics -/// -/// - when `but_vec` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `bit_vec` points to a valid [SPBitVec] -/// - `bit_vec` is not used concurrently or after this call -/// - `bit_vec` was not passed to another consuming function, e.g. to create a [TypedCommand] -/// -/// [TypedCommand]: [crate::TypedCommand] #[no_mangle] pub unsafe extern "C" fn sp_bitvec_free(bit_vec: NonNull) { _ = unsafe { Box::from_raw(bit_vec.as_ptr()) }; @@ -127,15 +74,7 @@ pub unsafe extern "C" fn sp_bitvec_free(bit_vec: NonNull) { /// /// # Panics /// -/// - when `bit_vec` is NULL /// - when accessing `index` out of bounds -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `bit_vec` points to a valid [SPBitVec] -/// - `bit_vec` is not written to concurrently #[no_mangle] pub unsafe extern "C" fn sp_bitvec_get( bit_vec: NonNull, @@ -154,15 +93,7 @@ pub unsafe extern "C" fn sp_bitvec_get( /// /// # Panics /// -/// - when `bit_vec` is NULL /// - when accessing `index` out of bounds -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `bit_vec` points to a valid [SPBitVec] -/// - `bit_vec` is not written to or read from concurrently #[no_mangle] pub unsafe extern "C" fn sp_bitvec_set( bit_vec: NonNull, @@ -178,17 +109,6 @@ pub unsafe extern "C" fn sp_bitvec_set( /// /// - `bit_vec`: instance to write to /// - `value`: the value to set all bits to -/// -/// # Panics -/// -/// - when `bit_vec` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `bit_vec` points to a valid [SPBitVec] -/// - `bit_vec` is not written to or read from concurrently #[no_mangle] pub unsafe extern "C" fn sp_bitvec_fill( bit_vec: NonNull, @@ -202,16 +122,6 @@ pub unsafe extern "C" fn sp_bitvec_fill( /// # Arguments /// /// - `bit_vec`: instance to write to -/// -/// # Panics -/// -/// - when `bit_vec` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `bit_vec` points to a valid [SPBitVec] #[no_mangle] pub unsafe extern "C" fn sp_bitvec_len(bit_vec: NonNull) -> usize { unsafe { bit_vec.as_ref().0.len() } @@ -222,16 +132,6 @@ pub unsafe extern "C" fn sp_bitvec_len(bit_vec: NonNull) -> usize { /// # Arguments /// /// - `bit_vec`: instance to write to -/// -/// # Panics -/// -/// - when `bit_vec` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `bit_vec` points to a valid [SPBitVec] #[no_mangle] pub unsafe extern "C" fn sp_bitvec_is_empty( bit_vec: NonNull, @@ -241,24 +141,14 @@ pub unsafe extern "C" fn sp_bitvec_is_empty( /// Gets an unsafe reference to the data of the [SPBitVec] instance. /// +/// The returned memory is valid for the lifetime of the bitvec. +/// /// # Arguments /// /// - `bit_vec`: instance to write to -/// -/// # Panics -/// -/// - when `bit_vec` is NULL -/// -/// ## Safety -/// -/// The caller has to make sure that: -/// -/// - `bit_vec` points to a valid [SPBitVec] -/// - the returned memory range is never accessed after the passed [SPBitVec] has been freed -/// - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly #[no_mangle] pub unsafe extern "C" fn sp_bitvec_unsafe_data_ref( bit_vec: NonNull, -) -> SPByteSlice { - unsafe { SPByteSlice::from_slice((*bit_vec.as_ptr()).0.as_raw_mut_slice()) } +) -> ByteSlice { + unsafe { ByteSlice::from_slice((*bit_vec.as_ptr()).0.as_raw_mut_slice()) } } diff --git a/src/brightness_grid.rs b/src/brightness_grid.rs index ff40ef9..5cd7a16 100644 --- a/src/brightness_grid.rs +++ b/src/brightness_grid.rs @@ -1,39 +1,25 @@ -//! C functions for interacting with [BrightnessGrid]s -//! -//! prefix `sp_brightness_grid_` -//! -//! -//! A grid containing brightness values. -//! -//! # Examples -//! ```C -//! UdpConnection connection = sp_connection_open("127.0.0.1:2342"); -//! if (connection == NULL) -//! return 1; -//! -//! BrightnessGrid grid = sp_brightness_grid_new(2, 2); -//! sp_brightness_grid_set(grid, 0, 0, 0); -//! sp_brightness_grid_set(grid, 1, 1, 10); -//! -//! TypedCommand command = sp_command_char_brightness(grid); -//! sp_connection_free(connection); -//! ``` - -use crate::SPByteSlice; -use servicepoint::{Brightness, BrightnessGrid, DataRef, Grid}; +use crate::ByteSlice; +use servicepoint::{Brightness, BrightnessGrid, ByteGrid, DataRef, Grid}; use std::mem::transmute; use std::ptr::NonNull; /// Creates a new [BrightnessGrid] with the specified dimensions. /// -/// returns: [BrightnessGrid] initialized to 0. Will never return NULL. +/// returns: [BrightnessGrid] initialized to 0. /// -/// # Safety +/// # Examples +/// ```C +/// UdpConnection connection = sp_connection_open("127.0.0.1:2342"); +/// if (connection == NULL) +/// return 1; /// -/// The caller has to make sure that: +/// BrightnessGrid grid = sp_brightness_grid_new(2, 2); +/// sp_brightness_grid_set(grid, 0, 0, 0); +/// sp_brightness_grid_set(grid, 1, 1, 10); /// -/// - the returned instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_brightness_grid_free`. +/// TypedCommand command = sp_command_char_brightness(grid); +/// sp_connection_free(connection); +/// ``` #[no_mangle] pub unsafe extern "C" fn sp_brightness_grid_new( width: usize, @@ -45,29 +31,15 @@ pub unsafe extern "C" fn sp_brightness_grid_new( /// Loads a [BrightnessGrid] with the specified dimensions from the provided data. /// -/// returns: new [BrightnessGrid] instance. Will never return NULL. -/// -/// # Panics -/// -/// - when `data` is NULL -/// - when the provided `data_length` does not match `height` and `width` -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `data` points to a valid memory location of at least `data_length` -/// bytes in size. -/// - the returned instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_brightness_grid_free`. +/// returns: new [BrightnessGrid] instance, or NULL in case of an error. #[no_mangle] pub unsafe extern "C" fn sp_brightness_grid_load( width: usize, height: usize, - data: SPByteSlice, + data: ByteSlice, ) -> *mut BrightnessGrid { let data = unsafe { data.as_slice() }; - let grid = match servicepoint::ByteGrid::load(width, height, data) { + let grid = match ByteGrid::load(width, height, data) { None => return std::ptr::null_mut(), Some(grid) => grid, }; @@ -79,25 +51,6 @@ pub unsafe extern "C" fn sp_brightness_grid_load( } /// Clones a [BrightnessGrid]. -/// -/// # Arguments -/// -/// - `brightness_grid`: instance to read from -/// -/// returns: new [BrightnessGrid] instance. Will never return NULL. -/// -/// # Panics -/// -/// - when `brightness_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `brightness_grid` points to a valid [BrightnessGrid] -/// - `brightness_grid` is not written to concurrently -/// - the returned instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_brightness_grid_free`. #[no_mangle] pub unsafe extern "C" fn sp_brightness_grid_clone( brightness_grid: NonNull, @@ -107,24 +60,6 @@ pub unsafe extern "C" fn sp_brightness_grid_clone( } /// Deallocates a [BrightnessGrid]. -/// -/// # Arguments -/// -/// - `brightness_grid`: instance to read from -/// -/// # Panics -/// -/// - when `brightness_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `brightness_grid` points to a valid [BrightnessGrid] -/// - `brightness_grid` is not used concurrently or after this call -/// - `brightness_grid` was not passed to another consuming function, e.g. to create a [TypedCommand] -/// -/// [TypedCommand]: [crate::TypedCommand] #[no_mangle] pub unsafe extern "C" fn sp_brightness_grid_free( brightness_grid: NonNull, @@ -142,16 +77,7 @@ pub unsafe extern "C" fn sp_brightness_grid_free( /// returns: value at position /// /// # Panics -/// -/// - when `brightness_grid` is NULL /// - When accessing `x` or `y` out of bounds. -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `brightness_grid` points to a valid [BrightnessGrid] -/// - `brightness_grid` is not written to concurrently #[no_mangle] pub unsafe extern "C" fn sp_brightness_grid_get( brightness_grid: NonNull, @@ -173,16 +99,7 @@ pub unsafe extern "C" fn sp_brightness_grid_get( /// /// # Panics /// -/// - when `brightness_grid` is NULL /// - When accessing `x` or `y` out of bounds. -/// - When providing an invalid brightness value -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `brightness_grid` points to a valid [BrightnessGrid] -/// - `brightness_grid` is not written to or read from concurrently #[no_mangle] pub unsafe extern "C" fn sp_brightness_grid_set( brightness_grid: NonNull, @@ -199,18 +116,6 @@ pub unsafe extern "C" fn sp_brightness_grid_set( /// /// - `brightness_grid`: instance to write to /// - `value`: the value to set all cells to -/// -/// # Panics -/// -/// - when `brightness_grid` is NULL -/// - When providing an invalid brightness value -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `brightness_grid` points to a valid [BrightnessGrid] -/// - `brightness_grid` is not written to or read from concurrently #[no_mangle] pub unsafe extern "C" fn sp_brightness_grid_fill( brightness_grid: NonNull, @@ -226,16 +131,6 @@ pub unsafe extern "C" fn sp_brightness_grid_fill( /// - `brightness_grid`: instance to read from /// /// returns: width -/// -/// # Panics -/// -/// - when `brightness_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `brightness_grid` points to a valid [BrightnessGrid] #[no_mangle] pub unsafe extern "C" fn sp_brightness_grid_width( brightness_grid: NonNull, @@ -250,16 +145,6 @@ pub unsafe extern "C" fn sp_brightness_grid_width( /// - `brightness_grid`: instance to read from /// /// returns: height -/// -/// # Panics -/// -/// - when `brightness_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `brightness_grid` points to a valid [BrightnessGrid] #[no_mangle] pub unsafe extern "C" fn sp_brightness_grid_height( brightness_grid: NonNull, @@ -269,30 +154,20 @@ pub unsafe extern "C" fn sp_brightness_grid_height( /// Gets an unsafe reference to the data of the [BrightnessGrid] instance. /// +/// The returned memory is valid for the lifetime of the brightness grid. +/// /// # Arguments /// /// - `brightness_grid`: instance to read from /// /// returns: slice of bytes underlying the `brightness_grid`. -/// -/// # Panics -/// -/// - when `brightness_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `brightness_grid` points to a valid [BrightnessGrid] -/// - the returned memory range is never accessed after the passed [BrightnessGrid] has been freed -/// - the returned memory range is never accessed concurrently, either via the [BrightnessGrid] or directly #[no_mangle] pub unsafe extern "C" fn sp_brightness_grid_unsafe_data_ref( brightness_grid: NonNull, -) -> SPByteSlice { +) -> ByteSlice { //noinspection RsAssertEqual const _: () = assert!(size_of::() == 1); let data = unsafe { (*brightness_grid.as_ptr()).data_ref_mut() }; - unsafe { SPByteSlice::from_slice(transmute(data)) } + unsafe { ByteSlice::from_slice(transmute(data)) } } diff --git a/src/byte_slice.rs b/src/byte_slice.rs index 066a405..001a616 100644 --- a/src/byte_slice.rs +++ b/src/byte_slice.rs @@ -2,9 +2,7 @@ use std::ptr::NonNull; -/// Represents a span of memory (`&mut [u8]` ) as a struct usable by C code. -/// -/// You should not create an instance of this type in your C code. +/// Represents a span of memory (`&mut [u8]` ) as a struct. /// /// # Safety /// @@ -13,17 +11,15 @@ use std::ptr::NonNull; /// - accesses to the memory pointed to with `start` is never accessed outside `length` /// - the lifetime of the `CByteSlice` does not outlive the memory it points to, as described in /// the function returning this type. -/// - an instance of this created from C is never passed to a consuming function, as the rust code -/// will try to free the memory of a potentially separate allocator. #[repr(C)] -pub struct SPByteSlice { - /// The start address of the memory +pub struct ByteSlice { + /// The start address of the memory. pub start: NonNull, - /// The amount of memory in bytes + /// The amount of memory in bytes. pub length: usize, } -impl SPByteSlice { +impl ByteSlice { pub(crate) unsafe fn as_slice(&self) -> &[u8] { unsafe { std::slice::from_raw_parts(self.start.as_ptr(), self.length) } } diff --git a/src/char_grid.rs b/src/char_grid.rs index 30e9953..a287d70 100644 --- a/src/char_grid.rs +++ b/src/char_grid.rs @@ -1,37 +1,19 @@ -//! C functions for interacting with [CharGrid]s -//! -//! prefix `sp_char_grid_` -//! -//! A C-wrapper for grid containing UTF-8 characters. -//! -//! As the rust [char] type is not FFI-safe, characters are passed in their UTF-32 form as 32bit unsigned integers. -//! -//! The encoding is enforced in most cases by the rust standard library -//! and will panic when provided with illegal characters. -//! -//! # Examples -//! -//! ```C -//! CharGrid grid = sp_char_grid_new(4, 3); -//! sp_char_grid_fill(grid, '?'); -//! sp_char_grid_set(grid, 0, 0, '!'); -//! sp_char_grid_free(grid); -//! ``` - -use crate::SPByteSlice; +use crate::ByteSlice; use servicepoint::{CharGrid, Grid}; use std::ptr::NonNull; /// Creates a new [CharGrid] with the specified dimensions. /// -/// returns: [CharGrid] initialized to 0. Will never return NULL. +/// returns: [CharGrid] initialized to 0. /// -/// # Safety +/// # Examples /// -/// The caller has to make sure that: -/// -/// - the returned instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_char_grid_free`. +/// ```C +/// CharGrid grid = sp_char_grid_new(4, 3); +/// sp_char_grid_fill(grid, '?'); +/// sp_char_grid_set(grid, 0, 0, '!'); +/// sp_char_grid_free(grid); +/// ``` #[no_mangle] pub unsafe extern "C" fn sp_char_grid_new( width: usize, @@ -43,80 +25,37 @@ pub unsafe extern "C" fn sp_char_grid_new( /// Loads a [CharGrid] with the specified dimensions from the provided data. /// -/// Will never return NULL. -/// -/// # Panics -/// -/// - when `data` is NULL -/// - when the provided `data_length` does not match `height` and `width` -/// - when `data` is not valid UTF-8 -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `data` points to a valid memory location of at least `data_length` -/// bytes in size. -/// - the returned instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_char_grid_free`. +/// returns: new CharGrid or NULL in case of an error #[no_mangle] pub unsafe extern "C" fn sp_char_grid_load( width: usize, height: usize, - data: SPByteSlice, -) -> NonNull { + data: ByteSlice, +) -> *mut CharGrid { let data = unsafe { data.as_slice() }; - // TODO remove unwrap - let result = - Box::new(CharGrid::load_utf8(width, height, data.to_vec()).unwrap()); - NonNull::from(Box::leak(result)) + if let Ok(grid) = CharGrid::load_utf8(width, height, data.to_vec()) { + Box::leak(Box::new(grid)) + } else { + std::ptr::null_mut() + } } /// Clones a [CharGrid]. -/// -/// Will never return NULL. -/// -/// # Panics -/// -/// - when `char_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `char_grid` points to a valid [CharGrid] -/// - `char_grid` is not written to concurrently -/// - the returned instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_char_grid_free`. #[no_mangle] pub unsafe extern "C" fn sp_char_grid_clone( char_grid: NonNull, ) -> NonNull { - let result = Box::new(unsafe { char_grid.as_ref().clone() }); - NonNull::from(Box::leak(result)) + let result = unsafe { char_grid.as_ref().clone() }; + NonNull::from(Box::leak(Box::new(result))) } /// Deallocates a [CharGrid]. -/// -/// # Panics -/// -/// - when `char_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `char_grid` points to a valid [CharGrid] -/// - `char_grid` is not used concurrently or after char_grid call -/// - `char_grid` was not passed to another consuming function, e.g. to create a [TypedCommand] -/// -/// [TypedCommand]: [crate::TypedCommand] #[no_mangle] pub unsafe extern "C" fn sp_char_grid_free(char_grid: NonNull) { _ = unsafe { Box::from_raw(char_grid.as_ptr()) }; } -/// Gets the current value at the specified position. +/// Returns the current value at the specified position. /// /// # Arguments /// @@ -125,15 +64,7 @@ pub unsafe extern "C" fn sp_char_grid_free(char_grid: NonNull) { /// /// # Panics /// -/// - when `char_grid` is NULL /// - when accessing `x` or `y` out of bounds -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `char_grid` points to a valid [CharGrid] -/// - `char_grid` is not written to concurrently #[no_mangle] pub unsafe extern "C" fn sp_char_grid_get( char_grid: NonNull, @@ -155,17 +86,7 @@ pub unsafe extern "C" fn sp_char_grid_get( /// /// # Panics /// -/// - when `char_grid` is NULL /// - when accessing `x` or `y` out of bounds -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `char_grid` points to a valid [SPBitVec] -/// - `char_grid` is not written to or read from concurrently -/// -/// [SPBitVec]: [crate::SPBitVec] #[no_mangle] pub unsafe extern "C" fn sp_char_grid_set( char_grid: NonNull, @@ -182,17 +103,6 @@ pub unsafe extern "C" fn sp_char_grid_set( /// /// - `char_grid`: instance to write to /// - `value`: the value to set all cells to -/// -/// # Panics -/// -/// - when `char_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `char_grid` points to a valid [CharGrid] -/// - `char_grid` is not written to or read from concurrently #[no_mangle] pub unsafe extern "C" fn sp_char_grid_fill( char_grid: NonNull, @@ -206,16 +116,6 @@ pub unsafe extern "C" fn sp_char_grid_fill( /// # Arguments /// /// - `char_grid`: instance to read from -/// -/// # Panics -/// -/// - when `char_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `char_grid` points to a valid [CharGrid] #[no_mangle] pub unsafe extern "C" fn sp_char_grid_width( char_grid: NonNull, @@ -228,16 +128,6 @@ pub unsafe extern "C" fn sp_char_grid_width( /// # Arguments /// /// - `char_grid`: instance to read from -/// -/// # Panics -/// -/// - when `char_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `char_grid` points to a valid [CharGrid] #[no_mangle] pub unsafe extern "C" fn sp_char_grid_height( char_grid: NonNull, diff --git a/src/command.rs b/src/command.rs index 2ed7415..b867eba 100644 --- a/src/command.rs +++ b/src/command.rs @@ -1,43 +1,12 @@ -//! C functions for interacting with [TypedCommand]s -//! -//! prefix `sp_command_` - use crate::SPBitVec; use servicepoint::{BinaryOperation, Bitmap, Brightness, BrightnessGrid, CharGrid, CompressionCode, Cp437Grid, GlobalBrightnessCommand, Packet, TypedCommand}; use std::ptr::NonNull; -/// A low-level display command. -/// -/// This struct and associated functions implement the UDP protocol for the display. -/// -/// To send a [TypedCommand], use a [UdpConnection]. -/// -/// # Examples -/// -/// ```C -/// sp_connection_send_command(connection, sp_command_clear()); -/// sp_connection_send_command(connection, sp_command_brightness(5)); -/// ``` - /// Tries to turn a [Packet] into a [TypedCommand]. /// /// The packet is deallocated in the process. /// /// Returns: pointer to new [TypedCommand] instance or NULL if parsing failed. -/// -/// # Panics -/// -/// - when `packet` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - [Packet] points to a valid instance of [Packet] -/// - [Packet] is not used concurrently or after this call -/// - the result is checked for NULL -/// - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_command_free`. #[no_mangle] pub unsafe extern "C" fn sp_command_try_from_packet( packet: NonNull, @@ -51,20 +20,7 @@ pub unsafe extern "C" fn sp_command_try_from_packet( /// Clones a [TypedCommand] instance. /// -/// returns: new [TypedCommand] instance. Will never return NULL. -/// -/// # Panics -/// -/// - when `command` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `command` points to a valid instance of [TypedCommand] -/// - `command` is not written to concurrently -/// - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_command_free`. +/// returns: new [TypedCommand] instance. #[no_mangle] pub unsafe extern "C" fn sp_command_clone( command: NonNull, @@ -77,20 +33,13 @@ pub unsafe extern "C" fn sp_command_clone( /// /// Does not affect brightness. /// -/// Returns: a new [servicepoint::Command::Clear] instance. Will never return NULL. +/// Returns: a new [servicepoint::Command::Clear] instance. /// /// # Examples /// /// ```C /// sp_connection_send_command(connection, sp_command_clear()); /// ``` -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_command_free`. #[no_mangle] pub unsafe extern "C" fn sp_command_clear() -> NonNull { let result = Box::new(servicepoint::ClearCommand.into()); @@ -101,14 +50,7 @@ pub unsafe extern "C" fn sp_command_clear() -> NonNull { /// /// Please do not send this in your normal program flow. /// -/// Returns: a new [servicepoint::Command::HardReset] instance. Will never return NULL. -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_command_free`. +/// Returns: a new [servicepoint::Command::HardReset] instance. #[no_mangle] pub unsafe extern "C" fn sp_command_hard_reset() -> NonNull { let result = Box::new(servicepoint::HardResetCommand.into()); @@ -117,14 +59,7 @@ pub unsafe extern "C" fn sp_command_hard_reset() -> NonNull { /// A yet-to-be-tested command. /// -/// Returns: a new [servicepoint::Command::FadeOut] instance. Will never return NULL. -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_command_free`. +/// Returns: a new [servicepoint::Command::FadeOut] instance. #[no_mangle] pub unsafe extern "C" fn sp_command_fade_out() -> NonNull { let result = Box::new(servicepoint::FadeOutCommand.into()); @@ -133,18 +68,7 @@ pub unsafe extern "C" fn sp_command_fade_out() -> NonNull { /// Set the brightness of all tiles to the same value. /// -/// Returns: a new [servicepoint::Command::Brightness] instance. Will never return NULL. -/// -/// # Panics -/// -/// - When the provided brightness value is out of range (0-11). -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_command_free`. +/// Returns: a new [servicepoint::Command::Brightness] instance. #[no_mangle] pub unsafe extern "C" fn sp_command_brightness( brightness: Brightness, @@ -157,20 +81,7 @@ pub unsafe extern "C" fn sp_command_brightness( /// /// The passed [BrightnessGrid] gets consumed. /// -/// Returns: a new [servicepoint::Command::CharBrightness] instance. Will never return NULL. -/// -/// # Panics -/// -/// - when `grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `grid` points to a valid instance of [BrightnessGrid] -/// - `grid` is not used concurrently or after this call -/// - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_command_free`. +/// Returns: a new [servicepoint::Command::CharBrightness] instance. #[no_mangle] pub unsafe extern "C" fn sp_command_char_brightness( x: usize, @@ -197,22 +108,7 @@ pub unsafe extern "C" fn sp_command_char_brightness( /// /// The passed [SPBitVec] gets consumed. /// -/// Returns: a new [servicepoint::Command::BitmapLinear] instance. Will never return NULL. -/// -/// # Panics -/// -/// - when `bit_vec` is null -/// - when `compression_code` is not a valid value -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `bit_vec` points to a valid instance of [SPBitVec] -/// - `bit_vec` is not used concurrently or after this call -/// - `compression` matches one of the allowed enum values -/// - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_command_free`. +/// Returns: a new [servicepoint::Command::BitmapLinear] instance. #[no_mangle] pub unsafe extern "C" fn sp_command_bitmap_linear( offset: usize, @@ -238,22 +134,7 @@ pub unsafe extern "C" fn sp_command_bitmap_linear( /// /// The passed [SPBitVec] gets consumed. /// -/// Returns: a new [servicepoint::Command::BitmapLinearAnd] instance. Will never return NULL. -/// -/// # Panics -/// -/// - when `bit_vec` is null -/// - when `compression_code` is not a valid value -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `bit_vec` points to a valid instance of [SPBitVec] -/// - `bit_vec` is not used concurrently or after this call -/// - `compression` matches one of the allowed enum values -/// - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_command_free`. +/// Returns: a new [servicepoint::Command::BitmapLinearAnd] instance. #[no_mangle] pub unsafe extern "C" fn sp_command_bitmap_linear_and( offset: usize, @@ -279,22 +160,7 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_and( /// /// The passed [SPBitVec] gets consumed. /// -/// Returns: a new [servicepoint::Command::BitmapLinearOr] instance. Will never return NULL. -/// -/// # Panics -/// -/// - when `bit_vec` is null -/// - when `compression_code` is not a valid value -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `bit_vec` points to a valid instance of [SPBitVec] -/// - `bit_vec` is not used concurrently or after this call -/// - `compression` matches one of the allowed enum values -/// - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_command_free`. +/// Returns: a new [servicepoint::Command::BitmapLinearOr] instance. #[no_mangle] pub unsafe extern "C" fn sp_command_bitmap_linear_or( offset: usize, @@ -320,22 +186,7 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_or( /// /// The passed [SPBitVec] gets consumed. /// -/// Returns: a new [servicepoint::Command::BitmapLinearXor] instance. Will never return NULL. -/// -/// # Panics -/// -/// - when `bit_vec` is null -/// - when `compression_code` is not a valid value -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `bit_vec` points to a valid instance of [SPBitVec] -/// - `bit_vec` is not used concurrently or after this call -/// - `compression` matches one of the allowed enum values -/// - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_command_free`. +/// Returns: a new [servicepoint::Command::BitmapLinearXor] instance. #[no_mangle] pub unsafe extern "C" fn sp_command_bitmap_linear_xor( offset: usize, @@ -352,7 +203,6 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_xor( } } -#[inline] unsafe fn sp_command_bitmap_linear_internal( offset: usize, bit_vec: NonNull, @@ -378,20 +228,7 @@ unsafe fn sp_command_bitmap_linear_internal( /// /// The passed [Cp437Grid] gets consumed. /// -/// Returns: a new [servicepoint::Command::Cp437Data] instance. Will never return NULL. -/// -/// # Panics -/// -/// - when `grid` is null -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `grid` points to a valid instance of [Cp437Grid] -/// - `grid` is not used concurrently or after this call -/// - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_command_free`. +/// Returns: a new [servicepoint::Command::Cp437Data] instance. #[no_mangle] pub unsafe extern "C" fn sp_command_cp437_data( x: usize, @@ -413,20 +250,7 @@ pub unsafe extern "C" fn sp_command_cp437_data( /// /// The passed [CharGrid] gets consumed. /// -/// Returns: a new [servicepoint::Command::Utf8Data] instance. Will never return NULL. -/// -/// # Panics -/// -/// - when `grid` is null -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `grid` points to a valid instance of [CharGrid] -/// - `grid` is not used concurrently or after this call -/// - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_command_free`. +/// Returns: a new [servicepoint::Command::Utf8Data] instance. #[no_mangle] pub unsafe extern "C" fn sp_command_utf8_data( x: usize, @@ -448,22 +272,7 @@ pub unsafe extern "C" fn sp_command_utf8_data( /// /// The passed [Bitmap] gets consumed. /// -/// Returns: a new [servicepoint::Command::BitmapLinearWin] instance. Will never return NULL. -/// -/// # Panics -/// -/// - when `bitmap` is null -/// - when `compression_code` is not a valid value -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `bitmap` points to a valid instance of [Bitmap] -/// - `bitmap` is not used concurrently or after this call -/// - `compression` matches one of the allowed enum values -/// - the returned [TypedCommand] instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_command_free`. +/// Returns: a new [servicepoint::Command::BitmapLinearWin] instance. #[no_mangle] pub unsafe extern "C" fn sp_command_bitmap_linear_win( x: usize, @@ -493,18 +302,6 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_win( /// TypedCommand c = sp_command_clear(); /// sp_command_free(c); /// ``` -/// -/// # Panics -/// -/// - when `command` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `command` points to a valid [TypedCommand] -/// - `command` is not used concurrently or after this call -/// - `command` was not passed to another consuming function, e.g. to create a [Packet] #[no_mangle] pub unsafe extern "C" fn sp_command_free(command: NonNull) { _ = unsafe { Box::from_raw(command.as_ptr()) }; diff --git a/src/connection.rs b/src/connection.rs index 79e2e33..5feb528 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -1,17 +1,3 @@ -//! C functions for interacting with [UdpConnection]s -//! -//! prefix `sp_connection_` -//! -//! A connection to the display. -//! -//! # Examples -//! -//! ```C -//! CConnection connection = sp_connection_open("172.23.42.29:2342"); -//! if (connection != NULL) -//! sp_connection_send_command(connection, sp_command_clear()); -//! ``` - use servicepoint::{Connection, Packet, TypedCommand, UdpConnection}; use std::ffi::{c_char, CStr}; use std::ptr::NonNull; @@ -20,16 +6,13 @@ use std::ptr::NonNull; /// /// returns: NULL if connection fails, or connected instance /// -/// # Panics +/// # Examples /// -/// - when `host` is null or an invalid host -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - the returned instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_connection_free`. +/// ```C +/// CConnection connection = sp_connection_open("172.23.42.29:2342"); +/// if (connection != NULL) +/// sp_connection_send_command(connection, sp_command_clear()); +/// ``` #[no_mangle] pub unsafe extern "C" fn sp_connection_open( host: NonNull, @@ -59,7 +42,7 @@ pub unsafe extern "C" fn sp_connection_open( // /// Creates a new instance of [SPUdpConnection] for testing that does not actually send anything. // /// -// /// returns: a new instance. Will never return NULL. +// /// returns: a new instance. // /// // /// # Safety // /// @@ -78,19 +61,6 @@ pub unsafe extern "C" fn sp_connection_open( /// The passed `packet` gets consumed. /// /// returns: true in case of success -/// -/// # Panics -/// -/// - when `connection` is NULL -/// - when `packet` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `connection` points to a valid instance of [UdpConnection] -/// - `packet` points to a valid instance of [Packet] -/// - `packet` is not used concurrently or after this call #[no_mangle] pub unsafe extern "C" fn sp_connection_send_packet( connection: NonNull, @@ -106,18 +76,12 @@ pub unsafe extern "C" fn sp_connection_send_packet( /// /// returns: true in case of success /// -/// # Panics +/// # Examples /// -/// - when `connection` is NULL -/// - when `command` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `connection` points to a valid instance of [UdpConnection] -/// - `command` points to a valid instance of [Packet] -/// - `command` is not used concurrently or after this call +/// ```C +/// sp_connection_send_command(connection, sp_command_clear()); +/// sp_connection_send_command(connection, sp_command_brightness(5)); +/// ``` #[no_mangle] pub unsafe extern "C" fn sp_connection_send_command( connection: NonNull, @@ -128,17 +92,6 @@ pub unsafe extern "C" fn sp_connection_send_command( } /// Closes and deallocates a [UdpConnection]. -/// -/// # Panics -/// -/// - when `connection` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `connection` points to a valid [UdpConnection] -/// - `connection` is not used concurrently or after this call #[no_mangle] pub unsafe extern "C" fn sp_connection_free( connection: NonNull, diff --git a/src/cp437_grid.rs b/src/cp437_grid.rs index 96db2db..3904354 100644 --- a/src/cp437_grid.rs +++ b/src/cp437_grid.rs @@ -1,35 +1,10 @@ -//! C functions for interacting with [Cp437Grid]s -//! -//! prefix `sp_cp437_grid_` -//! -//! -//! A C-wrapper for grid containing codepage 437 characters. -//! -//! The encoding is currently not enforced. -//! -//! # Examples -//! -//! ```C -//! Cp437Grid grid = sp_cp437_grid_new(4, 3); -//! sp_cp437_grid_fill(grid, '?'); -//! sp_cp437_grid_set(grid, 0, 0, '!'); -//! sp_cp437_grid_free(grid); -//! ``` - -use crate::SPByteSlice; +use crate::ByteSlice; use servicepoint::{Cp437Grid, DataRef, Grid}; use std::ptr::NonNull; /// Creates a new [Cp437Grid] with the specified dimensions. /// -/// returns: [Cp437Grid] initialized to 0. Will never return NULL. -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - the returned instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_cp437_grid_free`. +/// returns: [Cp437Grid] initialized to 0. #[no_mangle] pub unsafe extern "C" fn sp_cp437_grid_new( width: usize, @@ -40,27 +15,11 @@ pub unsafe extern "C" fn sp_cp437_grid_new( } /// Loads a [Cp437Grid] with the specified dimensions from the provided data. -/// -/// Will never return NULL. -/// -/// # Panics -/// -/// - when `data` is NULL -/// - when the provided `data_length` does not match `height` and `width` -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `data` points to a valid memory location of at least `data_length` -/// bytes in size. -/// - the returned instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_cp437_grid_free`. #[no_mangle] pub unsafe extern "C" fn sp_cp437_grid_load( width: usize, height: usize, - data: SPByteSlice, + data: ByteSlice, ) -> *mut Cp437Grid { let data = unsafe { data.as_slice() }; let grid = Cp437Grid::load(width, height, data); @@ -72,21 +31,6 @@ pub unsafe extern "C" fn sp_cp437_grid_load( } /// Clones a [Cp437Grid]. -/// -/// Will never return NULL. -/// -/// # Panics -/// -/// - when `cp437_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `cp437_grid` points to a valid [Cp437Grid] -/// - `cp437_grid` is not written to concurrently -/// - the returned instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_cp437_grid_free`. #[no_mangle] pub unsafe extern "C" fn sp_cp437_grid_clone( cp437_grid: NonNull, @@ -96,20 +40,6 @@ pub unsafe extern "C" fn sp_cp437_grid_clone( } /// Deallocates a [Cp437Grid]. -/// -/// # Panics -/// -/// - when `cp437_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `cp437_grid` points to a valid [Cp437Grid] -/// - `cp437_grid` is not used concurrently or after cp437_grid call -/// - `cp437_grid` was not passed to another consuming function, e.g. to create a [TypedCommand] -/// -/// [TypedCommand]: [crate::TypedCommand] #[no_mangle] pub unsafe extern "C" fn sp_cp437_grid_free(cp437_grid: NonNull) { _ = unsafe { Box::from_raw(cp437_grid.as_ptr()) }; @@ -124,15 +54,7 @@ pub unsafe extern "C" fn sp_cp437_grid_free(cp437_grid: NonNull) { /// /// # Panics /// -/// - when `cp437_grid` is NULL /// - when accessing `x` or `y` out of bounds -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `cp437_grid` points to a valid [Cp437Grid] -/// - `cp437_grid` is not written to concurrently #[no_mangle] pub unsafe extern "C" fn sp_cp437_grid_get( cp437_grid: NonNull, @@ -154,17 +76,7 @@ pub unsafe extern "C" fn sp_cp437_grid_get( /// /// # Panics /// -/// - when `cp437_grid` is NULL /// - when accessing `x` or `y` out of bounds -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `cp437_grid` points to a valid [SPBitVec] -/// - `cp437_grid` is not written to or read from concurrently -/// -/// [SPBitVec]: [crate::SPBitVec] #[no_mangle] pub unsafe extern "C" fn sp_cp437_grid_set( cp437_grid: NonNull, @@ -181,17 +93,6 @@ pub unsafe extern "C" fn sp_cp437_grid_set( /// /// - `cp437_grid`: instance to write to /// - `value`: the value to set all cells to -/// -/// # Panics -/// -/// - when `cp437_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `cp437_grid` points to a valid [Cp437Grid] -/// - `cp437_grid` is not written to or read from concurrently #[no_mangle] pub unsafe extern "C" fn sp_cp437_grid_fill( cp437_grid: NonNull, @@ -205,16 +106,6 @@ pub unsafe extern "C" fn sp_cp437_grid_fill( /// # Arguments /// /// - `cp437_grid`: instance to read from -/// -/// # Panics -/// -/// - when `cp437_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `cp437_grid` points to a valid [Cp437Grid] #[no_mangle] pub unsafe extern "C" fn sp_cp437_grid_width( cp437_grid: NonNull, @@ -227,16 +118,6 @@ pub unsafe extern "C" fn sp_cp437_grid_width( /// # Arguments /// /// - `cp437_grid`: instance to read from -/// -/// # Panics -/// -/// - when `cp437_grid` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `cp437_grid` points to a valid [Cp437Grid] #[no_mangle] pub unsafe extern "C" fn sp_cp437_grid_height( cp437_grid: NonNull, @@ -246,22 +127,10 @@ pub unsafe extern "C" fn sp_cp437_grid_height( /// Gets an unsafe reference to the data of the [Cp437Grid] instance. /// -/// Will never return NULL. -/// -/// # Panics -/// -/// - when `cp437_grid` is NULL -/// -/// ## Safety -/// -/// The caller has to make sure that: -/// -/// - `cp437_grid` points to a valid [Cp437Grid] -/// - the returned memory range is never accessed after the passed [Cp437Grid] has been freed -/// - the returned memory range is never accessed concurrently, either via the [Cp437Grid] or directly +/// The returned memory is valid for the lifetime of the grid. #[no_mangle] pub unsafe extern "C" fn sp_cp437_grid_unsafe_data_ref( cp437_grid: NonNull, -) -> SPByteSlice { - unsafe { SPByteSlice::from_slice((*cp437_grid.as_ptr()).data_ref_mut()) } +) -> ByteSlice { + unsafe { ByteSlice::from_slice((*cp437_grid.as_ptr()).data_ref_mut()) } } diff --git a/src/packet.rs b/src/packet.rs index ae37058..996c83d 100644 --- a/src/packet.rs +++ b/src/packet.rs @@ -1,11 +1,4 @@ -//! C functions for interacting with [Packet]s -//! -//! prefix `sp_packet_` -//! -//! -//! The raw packet - -use crate::SPByteSlice; +use crate::ByteSlice; use servicepoint::{Header, Packet, TypedCommand}; use std::ptr::NonNull; @@ -13,19 +6,6 @@ use std::ptr::NonNull; /// The [TypedCommand] gets consumed. /// /// Returns NULL in case of an error. -/// -/// # Panics -/// -/// - when `command` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - [TypedCommand] points to a valid instance of [TypedCommand] -/// - [TypedCommand] is not used concurrently or after this call -/// - the returned [Packet] instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_packet_free`. #[no_mangle] pub unsafe extern "C" fn sp_packet_from_command( command: NonNull, @@ -41,21 +21,8 @@ pub unsafe extern "C" fn sp_packet_from_command( /// Tries to load a [Packet] from the passed array with the specified length. /// /// returns: NULL in case of an error, pointer to the allocated packet otherwise -/// -/// # Panics -/// -/// - when `data` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `data` points to a valid memory region of at least `length` bytes -/// - `data` is not written to concurrently -/// - the returned [Packet] instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_packet_free`. #[no_mangle] -pub unsafe extern "C" fn sp_packet_try_load(data: SPByteSlice) -> *mut Packet { +pub unsafe extern "C" fn sp_packet_try_load(data: ByteSlice) -> *mut Packet { let data = unsafe { data.as_slice() }; match servicepoint::Packet::try_from(data) { Err(_) => std::ptr::null_mut(), @@ -65,32 +32,11 @@ pub unsafe extern "C" fn sp_packet_try_load(data: SPByteSlice) -> *mut Packet { /// Creates a raw [Packet] from parts. /// -/// # Arguments -/// -/// - `command_code` specifies which command this packet contains -/// - `a`, `b`, `c` and `d` are command-specific header values -/// - `payload` is the optional data that is part of the command -/// - `payload_len` is the size of the payload -/// /// returns: new instance. Will never return null. -/// -/// # Panics -/// -/// - when `payload` is null, but `payload_len` is not zero -/// - when `payload_len` is zero, but `payload` is nonnull -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `payload` points to a valid memory region of at least `payload_len` bytes -/// - `payload` is not written to concurrently -/// - the returned [Packet] instance is freed in some way, either by using a consuming function or -/// by explicitly calling [sp_packet_free]. #[no_mangle] pub unsafe extern "C" fn sp_packet_from_parts( header: Header, - payload: *const SPByteSlice, + payload: *const ByteSlice, ) -> NonNull { let payload = if payload.is_null() { vec![] @@ -119,8 +65,8 @@ pub unsafe extern "C" fn sp_packet_get_header( #[no_mangle] pub unsafe extern "C" fn sp_packet_get_payload( packet: NonNull, -) -> SPByteSlice { - unsafe { SPByteSlice::from_slice(&mut *(*packet.as_ptr()).payload) } +) -> ByteSlice { + unsafe { ByteSlice::from_slice(&mut *(*packet.as_ptr()).payload) } } /// Sets the payload of the provided packet to the provided data. @@ -129,7 +75,7 @@ pub unsafe extern "C" fn sp_packet_get_payload( #[no_mangle] pub unsafe extern "C" fn sp_packet_set_payload( packet: NonNull, - data: SPByteSlice, + data: ByteSlice, ) { unsafe { (*packet.as_ptr()).payload = data.as_slice().to_vec() } } @@ -142,7 +88,7 @@ pub unsafe extern "C" fn sp_packet_set_payload( #[no_mangle] pub unsafe extern "C" fn sp_packet_serialize_to( packet: NonNull, - buffer: SPByteSlice, + buffer: ByteSlice, ) { unsafe { packet.as_ref().serialize_to(buffer.as_slice_mut()); @@ -150,21 +96,6 @@ pub unsafe extern "C" fn sp_packet_serialize_to( } /// Clones a [Packet]. -/// -/// Will never return NULL. -/// -/// # Panics -/// -/// - when `packet` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `packet` points to a valid [Packet] -/// - `packet` is not written to concurrently -/// - the returned instance is freed in some way, either by using a consuming function or -/// by explicitly calling `sp_packet_free`. #[no_mangle] pub unsafe extern "C" fn sp_packet_clone( packet: NonNull, @@ -174,17 +105,6 @@ pub unsafe extern "C" fn sp_packet_clone( } /// Deallocates a [Packet]. -/// -/// # Panics -/// -/// - when `packet` is NULL -/// -/// # Safety -/// -/// The caller has to make sure that: -/// -/// - `packet` points to a valid [Packet] -/// - `packet` is not used concurrently or after this call #[no_mangle] pub unsafe extern "C" fn sp_packet_free(packet: NonNull) { _ = unsafe { Box::from_raw(packet.as_ptr()) }