Compare commits

..

No commits in common. "b79a2534fc272e0889b56c13582e7ba3988378fb" and "21987d05f37ab5696b3fbbffe794507df65f1ce9" have entirely different histories.

14 changed files with 823 additions and 741 deletions

View file

@ -1,7 +1,7 @@
#ifndef SERVICEPOINT_BINDINGS_C #ifndef SERVICEPOINT_BINDINGS_C
#define SERVICEPOINT_BINDINGS_C #define SERVICEPOINT_BINDINGS_C
/* Generated with cbindgen:0.28.0 */ /* Generated with cbindgen:0.29.0 */
/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */ /* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */
@ -633,6 +633,12 @@ typedef struct Header {
extern "C" { extern "C" {
#endif // __cplusplus #endif // __cplusplus
/**
* Call this function at the beginning of main to enable rust logging controlled by the
* `RUST_LOG` environment variable. See [env_logger](https://docs.rs/env_logger/latest/env_logger/).
*/
void init_env_logger(void);
/** /**
*Clones a [`Bitmap`] instance. *Clones a [`Bitmap`] instance.
* *
@ -1248,14 +1254,14 @@ void sp_cmd_bitmap_free(struct BitmapCommand */*notnull*/ instance);
struct BitmapCommand */*notnull*/ sp_cmd_bitmap_from_bitmap(struct Bitmap */*notnull*/ bitmap); struct BitmapCommand */*notnull*/ sp_cmd_bitmap_from_bitmap(struct Bitmap */*notnull*/ bitmap);
/** /**
* Gets a reference to the field `bitmap` of the [`servicepoint::BitmapCommand`]. * Returns a pointer to the provided `BitmapCommand`.
* *
* - The returned reference inherits the lifetime of object in which it is contained. * # Safety
*
* - The returned bitmap inherits the lifetime of the command in which it is contained.
* - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command. * - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command.
*
* This function is part of the sp_cmd_bitmap module.
*/ */
struct Bitmap */*notnull*/ sp_cmd_bitmap_get_bitmap_mut(struct BitmapCommand */*notnull*/ instance); struct Bitmap */*notnull*/ sp_cmd_bitmap_get(struct BitmapCommand */*notnull*/ command);
/** /**
* Gets the value of field `compression` of the [`servicepoint::BitmapCommand`]. * Gets the value of field `compression` of the [`servicepoint::BitmapCommand`].
@ -1265,9 +1271,7 @@ struct Bitmap */*notnull*/ sp_cmd_bitmap_get_bitmap_mut(struct BitmapCommand */*
CompressionCode sp_cmd_bitmap_get_compression(struct BitmapCommand */*notnull*/ instance); CompressionCode sp_cmd_bitmap_get_compression(struct BitmapCommand */*notnull*/ instance);
/** /**
* Reads the origin field of the [`BitmapCommand`]. * Reads the origin field of the [BitmapCommand].
*
* This function is part of the sp_cmd_bitmap module.
*/ */
void sp_cmd_bitmap_get_origin(struct BitmapCommand */*notnull*/ command, void sp_cmd_bitmap_get_origin(struct BitmapCommand */*notnull*/ command,
size_t */*notnull*/ origin_x, size_t */*notnull*/ origin_x,
@ -1288,13 +1292,10 @@ struct BitmapCommand */*notnull*/ sp_cmd_bitmap_new(struct Bitmap */*notnull*/ b
CompressionCode compression); CompressionCode compression);
/** /**
* Sets the value of field `bitmap` of the [`servicepoint::BitmapCommand`]. * Moves the provided [Bitmap] to be contained in the [BitmapCommand].
* The provided value is moved into the instance, potentially invalidating previously taken references.
*
* This function is part of the sp_cmd_bitmap module.
*/ */
void sp_cmd_bitmap_set_bitmap(struct BitmapCommand */*notnull*/ instance, void sp_cmd_bitmap_set(struct BitmapCommand */*notnull*/ command,
struct Bitmap */*notnull*/ value); struct Bitmap */*notnull*/ bitmap);
/** /**
* Sets the value of field `compression` of the [`servicepoint::BitmapCommand`]. * Sets the value of field `compression` of the [`servicepoint::BitmapCommand`].
@ -1305,9 +1306,7 @@ void sp_cmd_bitmap_set_compression(struct BitmapCommand */*notnull*/ instance,
CompressionCode value); CompressionCode value);
/** /**
* Overwrites the origin field of the [`BitmapCommand`]. * Overwrites the origin field of the [BitmapCommand].
*
* This function is part of the sp_cmd_bitmap module.
*/ */
void sp_cmd_bitmap_set_origin(struct BitmapCommand */*notnull*/ command, void sp_cmd_bitmap_set_origin(struct BitmapCommand */*notnull*/ command,
size_t origin_x, size_t origin_x,
@ -1337,14 +1336,9 @@ struct BitVecCommand */*notnull*/ sp_cmd_bitvec_clone(struct BitVecCommand */*no
void sp_cmd_bitvec_free(struct BitVecCommand */*notnull*/ instance); void sp_cmd_bitvec_free(struct BitVecCommand */*notnull*/ instance);
/** /**
* Gets a reference to the field `bitvec` of the [`servicepoint::BitVecCommand`]. * Returns a pointer to the [BitVec] contained in the [BitVecCommand].
*
* - The returned reference inherits the lifetime of object in which it is contained.
* - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command.
*
* This function is part of the sp_cmd_bitvec module.
*/ */
BitVec */*notnull*/ sp_cmd_bitvec_get_bitvec_mut(struct BitVecCommand */*notnull*/ instance); BitVec *sp_cmd_bitvec_get(struct BitVecCommand */*notnull*/ command);
/** /**
* Gets the value of field `compression` of the [`servicepoint::BitVecCommand`]. * Gets the value of field `compression` of the [`servicepoint::BitVecCommand`].
@ -1389,13 +1383,10 @@ struct BitVecCommand */*notnull*/ sp_cmd_bitvec_new(BitVec */*notnull*/ bitvec,
CompressionCode compression); CompressionCode compression);
/** /**
* Sets the value of field `bitvec` of the [`servicepoint::BitVecCommand`]. * Moves the provided [BitVec] to be contained in the [BitVecCommand].
* The provided value is moved into the instance, potentially invalidating previously taken references.
*
* This function is part of the sp_cmd_bitvec module.
*/ */
void sp_cmd_bitvec_set_bitvec(struct BitVecCommand */*notnull*/ instance, void sp_cmd_bitvec_set(struct BitVecCommand */*notnull*/ command,
BitVec */*notnull*/ value); BitVec */*notnull*/ bitvec);
/** /**
* Sets the value of field `compression` of the [`servicepoint::BitVecCommand`]. * Sets the value of field `compression` of the [`servicepoint::BitVecCommand`].
@ -1498,19 +1489,12 @@ void sp_cmd_brightness_grid_free(struct BrightnessGridCommand */*notnull*/ insta
struct BrightnessGridCommand */*notnull*/ sp_cmd_brightness_grid_from_grid(BrightnessGrid */*notnull*/ grid); struct BrightnessGridCommand */*notnull*/ sp_cmd_brightness_grid_from_grid(BrightnessGrid */*notnull*/ grid);
/** /**
* Gets a reference to the field `grid` of the [`servicepoint::BrightnessGridCommand`]. * Returns a pointer to the [BrightnessGrid] contained in the [BrightnessGridCommand].
*
* - The returned reference inherits the lifetime of object in which it is contained.
* - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command.
*
* This function is part of the sp_cmd_brightness_grid module.
*/ */
BrightnessGrid */*notnull*/ sp_cmd_brightness_grid_get_grid_mut(struct BrightnessGridCommand */*notnull*/ instance); BrightnessGrid *sp_cmd_brightness_grid_get(struct BrightnessGridCommand */*notnull*/ command);
/** /**
* Reads the origin field of the [`BrightnessGridCommand`]. * Overwrites the origin field of the [BrightnessGridCommand].
*
* This function is part of the sp_cmd_brightness_grid module.
*/ */
void sp_cmd_brightness_grid_get_origin(struct BrightnessGridCommand */*notnull*/ command, void sp_cmd_brightness_grid_get_origin(struct BrightnessGridCommand */*notnull*/ command,
size_t */*notnull*/ origin_x, size_t */*notnull*/ origin_x,
@ -1539,18 +1523,13 @@ struct BrightnessGridCommand */*notnull*/ sp_cmd_brightness_grid_new(BrightnessG
size_t origin_y); size_t origin_y);
/** /**
* Sets the value of field `grid` of the [`servicepoint::BrightnessGridCommand`]. * Moves the provided [BrightnessGrid] to be contained in the [BrightnessGridCommand].
* The provided value is moved into the instance, potentially invalidating previously taken references.
*
* This function is part of the sp_cmd_brightness_grid module.
*/ */
void sp_cmd_brightness_grid_set_grid(struct BrightnessGridCommand */*notnull*/ instance, void sp_cmd_brightness_grid_set(struct BrightnessGridCommand */*notnull*/ command,
BrightnessGrid */*notnull*/ value); BrightnessGrid */*notnull*/ grid);
/** /**
* Overwrites the origin field of the [`BrightnessGridCommand`]. * Reads the origin field of the [BrightnessGridCommand].
*
* This function is part of the sp_cmd_brightness_grid module.
*/ */
void sp_cmd_brightness_grid_set_origin(struct BrightnessGridCommand */*notnull*/ command, void sp_cmd_brightness_grid_set_origin(struct BrightnessGridCommand */*notnull*/ command,
size_t origin_x, size_t origin_x,
@ -1579,19 +1558,12 @@ void sp_cmd_char_grid_free(struct CharGridCommand */*notnull*/ instance);
struct CharGridCommand */*notnull*/ sp_cmd_char_grid_from_grid(CharGrid */*notnull*/ grid); struct CharGridCommand */*notnull*/ sp_cmd_char_grid_from_grid(CharGrid */*notnull*/ grid);
/** /**
* Gets a reference to the field `grid` of the [`servicepoint::CharGridCommand`]. * Returns a pointer to the [CharGrid] contained in the [CharGridCommand].
*
* - The returned reference inherits the lifetime of object in which it is contained.
* - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command.
*
* This function is part of the sp_cmd_char_grid module.
*/ */
CharGrid */*notnull*/ sp_cmd_char_grid_get_grid_mut(struct CharGridCommand */*notnull*/ instance); CharGrid */*notnull*/ sp_cmd_char_grid_get(struct CharGridCommand */*notnull*/ command);
/** /**
* Reads the origin field of the [`CharGridCommand`]. * Reads the origin field of the [CharGridCommand].
*
* This function is part of the sp_cmd_char_grid module.
*/ */
void sp_cmd_char_grid_get_origin(struct CharGridCommand */*notnull*/ command, void sp_cmd_char_grid_get_origin(struct CharGridCommand */*notnull*/ command,
size_t */*notnull*/ origin_x, size_t */*notnull*/ origin_x,
@ -1611,18 +1583,13 @@ struct CharGridCommand */*notnull*/ sp_cmd_char_grid_new(CharGrid */*notnull*/ g
size_t origin_y); size_t origin_y);
/** /**
* Sets the value of field `grid` of the [`servicepoint::CharGridCommand`]. * Moves the provided [CharGrid] to be contained in the [CharGridCommand].
* The provided value is moved into the instance, potentially invalidating previously taken references.
*
* This function is part of the sp_cmd_char_grid module.
*/ */
void sp_cmd_char_grid_set_grid(struct CharGridCommand */*notnull*/ instance, void sp_cmd_char_grid_set(struct CharGridCommand */*notnull*/ command,
CharGrid */*notnull*/ value); CharGrid */*notnull*/ grid);
/** /**
* Overwrites the origin field of the [`CharGridCommand`]. * Overwrites the origin field of the [CharGridCommand].
*
* This function is part of the sp_cmd_char_grid module.
*/ */
void sp_cmd_char_grid_set_origin(struct CharGridCommand */*notnull*/ command, void sp_cmd_char_grid_set_origin(struct CharGridCommand */*notnull*/ command,
size_t origin_x, size_t origin_x,
@ -1649,7 +1616,7 @@ void sp_cmd_clear_free(struct ClearCommand */*notnull*/ instance);
* *
* Does not affect brightness. * Does not affect brightness.
* *
* Returns: a new [`ClearCommand`] instance. * Returns: a new [ClearCommand] instance.
* *
* This function is part of the sp_cmd_clear module. * This function is part of the sp_cmd_clear module.
*/ */
@ -1678,19 +1645,19 @@ void sp_cmd_cp437_grid_free(struct Cp437GridCommand */*notnull*/ instance);
struct Cp437GridCommand */*notnull*/ sp_cmd_cp437_grid_from_grid(Cp437Grid */*notnull*/ grid); struct Cp437GridCommand */*notnull*/ sp_cmd_cp437_grid_from_grid(Cp437Grid */*notnull*/ grid);
/** /**
* Gets a reference to the field `grid` of the [`servicepoint::Cp437GridCommand`]. * Show text on the screen.
* *
* - The returned reference inherits the lifetime of object in which it is contained. * The text is sent in the form of a 2D grid of [CP-437] encoded characters.
* - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command. * For sending UTF-8 encoded characters, see [servicepoint::CharGridCommand].
* *
* This function is part of the sp_cmd_cp437_grid module. * [CP-437]: https://en.wikipedia.org/wiki/Code_page_437
*/ */
Cp437Grid */*notnull*/ sp_cmd_cp437_grid_get_grid_mut(struct Cp437GridCommand */*notnull*/ instance); Cp437Grid *sp_cmd_cp437_grid_get(struct Cp437GridCommand */*notnull*/ command);
/** /**
* Reads the origin field of the [`Cp437GridCommand`]. * Gets the origin field of the [Cp437GridCommand].
* *
* This function is part of the sp_cmd_cp437_grid module. * Rust equivalent: `cp437_command.origin`
*/ */
void sp_cmd_cp437_grid_get_origin(struct Cp437GridCommand */*notnull*/ command, void sp_cmd_cp437_grid_get_origin(struct Cp437GridCommand */*notnull*/ command,
size_t */*notnull*/ origin_x, size_t */*notnull*/ origin_x,
@ -1710,18 +1677,17 @@ struct Cp437GridCommand */*notnull*/ sp_cmd_cp437_grid_new(Cp437Grid */*notnull*
size_t origin_y); size_t origin_y);
/** /**
* Sets the value of field `grid` of the [`servicepoint::Cp437GridCommand`]. * Moves the provided bitmap into the provided command.
* The provided value is moved into the instance, potentially invalidating previously taken references.
* *
* This function is part of the sp_cmd_cp437_grid module. * This drops the previously contained [Cp437Grid].
*/ */
void sp_cmd_cp437_grid_set_grid(struct Cp437GridCommand */*notnull*/ instance, void sp_cmd_cp437_grid_set(struct Cp437GridCommand */*notnull*/ command,
Cp437Grid */*notnull*/ value); Cp437Grid */*notnull*/ grid);
/** /**
* Overwrites the origin field of the [`Cp437GridCommand`]. * Sets the origin field of the [Cp437GridCommand].
* *
* This function is part of the sp_cmd_cp437_grid module. * Rust equivalent: `cp437_command.origin = Origin::new(origin_x, origin_y)`
*/ */
void sp_cmd_cp437_grid_set_origin(struct Cp437GridCommand */*notnull*/ command, void sp_cmd_cp437_grid_set_origin(struct Cp437GridCommand */*notnull*/ command,
size_t origin_x, size_t origin_x,
@ -1746,7 +1712,7 @@ void sp_cmd_fade_out_free(struct FadeOutCommand */*notnull*/ instance);
/** /**
* A yet-to-be-tested command. * A yet-to-be-tested command.
* *
* Returns: a new [`FadeOutCommand`] instance. * Returns: a new [FadeOutCommand] instance.
* *
* This function is part of the sp_cmd_fade_out module. * This function is part of the sp_cmd_fade_out module.
*/ */
@ -1756,8 +1722,6 @@ struct FadeOutCommand */*notnull*/ sp_cmd_fade_out_new(void);
* Clones an [SPCommand] instance. * Clones an [SPCommand] instance.
* *
* returns: a new [SPCommand] instance. * returns: a new [SPCommand] instance.
*
* This function is part of the sp_cmd_generic module.
*/ */
struct Command sp_cmd_generic_clone(struct Command command); struct Command sp_cmd_generic_clone(struct Command command);
@ -1772,8 +1736,6 @@ struct Command sp_cmd_generic_clone(struct Command command);
* SPCommand c = sp_cmd_clear_into_generic(sp_cmd_clear_new()); * SPCommand c = sp_cmd_clear_into_generic(sp_cmd_clear_new());
* sp_command_free(c); * sp_command_free(c);
* ``` * ```
*
* This function is part of the sp_cmd_generic module.
*/ */
void sp_cmd_generic_free(struct Command command); void sp_cmd_generic_free(struct Command command);
@ -1782,8 +1744,6 @@ void sp_cmd_generic_free(struct Command command);
* The [SPCommand] gets consumed. * The [SPCommand] gets consumed.
* *
* Returns tag [CommandTag::Invalid] in case of an error. * Returns tag [CommandTag::Invalid] in case of an error.
*
* This function is part of the sp_cmd_generic module.
*/ */
struct Packet *sp_cmd_generic_into_packet(struct Command command); struct Packet *sp_cmd_generic_into_packet(struct Command command);
@ -1793,8 +1753,6 @@ struct Packet *sp_cmd_generic_into_packet(struct Command command);
* The packet is dropped in the process. * The packet is dropped in the process.
* *
* Returns: pointer to new [SPCommand] instance or NULL if parsing failed. * Returns: pointer to new [SPCommand] instance or NULL if parsing failed.
*
* This function is part of the sp_cmd_generic module.
*/ */
struct Command sp_cmd_generic_try_from_packet(struct Packet */*notnull*/ packet); struct Command sp_cmd_generic_try_from_packet(struct Packet */*notnull*/ packet);
@ -1810,7 +1768,7 @@ void sp_cmd_hard_reset_free(struct HardResetCommand */*notnull*/ instance);
* *
* Please do not send this in your normal program flow. * Please do not send this in your normal program flow.
* *
* Returns: a new [`HardResetCommand`] instance. * Returns: a new [HardResetCommand] instance.
* *
* This function is part of the sp_cmd_hard_reset module. * This function is part of the sp_cmd_hard_reset module.
*/ */
@ -1944,14 +1902,6 @@ void sp_cp437_grid_set(Cp437Grid */*notnull*/ instance,
*/ */
size_t sp_cp437_grid_width(Cp437Grid */*notnull*/ instance); size_t sp_cp437_grid_width(Cp437Grid */*notnull*/ instance);
/**
* Call this function at the beginning of main to enable rust logging controlled by the
* `RUST_LOG` environment variable. See [env_logger](https://docs.rs/env_logger/latest/env_logger/).
*
* This function is part of the sp_envlogger module.
*/
void sp_envlogger_init(void);
/** /**
*Clones a [`Packet`] instance. *Clones a [`Packet`] instance.
* *
@ -1970,8 +1920,6 @@ void sp_packet_free(struct Packet */*notnull*/ instance);
* Creates a raw [Packet] from parts. * Creates a raw [Packet] from parts.
* *
* returns: new instance. Will never return null. * returns: new instance. Will never return null.
*
* This function is part of the sp_packet module.
*/ */
struct Packet */*notnull*/ sp_packet_from_parts(struct Header header, struct Packet */*notnull*/ sp_packet_from_parts(struct Header header,
struct ByteSlice payload); struct ByteSlice payload);
@ -1984,14 +1932,11 @@ struct Packet */*notnull*/ sp_packet_from_parts(struct Header header,
struct Header sp_packet_get_header(struct Packet */*notnull*/ instance); struct Header sp_packet_get_header(struct Packet */*notnull*/ instance);
/** /**
* Gets a reference to the field `header` of the [`servicepoint::Packet`]. * Returns a pointer to the header field of the provided packet.
* *
* - The returned reference inherits the lifetime of object in which it is contained. * The returned header can be changed and will be valid for the lifetime of the packet.
* - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command.
*
* This function is part of the sp_packet module.
*/ */
struct Header */*notnull*/ sp_packet_get_header_mut(struct Packet */*notnull*/ instance); struct Header */*notnull*/ sp_packet_get_header_mut(struct Packet */*notnull*/ packet);
/** /**
* Returns a pointer to the current payload of the provided packet. * Returns a pointer to the current payload of the provided packet.
@ -1999,8 +1944,6 @@ struct Header */*notnull*/ sp_packet_get_header_mut(struct Packet */*notnull*/ i
* Returns an [ByteSlice::INVALID] instance in case the packet does not have any payload. * Returns an [ByteSlice::INVALID] instance in case the packet does not have any payload.
* *
* The returned memory can be changed and will be valid until a new payload is set. * The returned memory can be changed and will be valid until a new payload is set.
*
* This function is part of the sp_packet module.
*/ */
struct ByteSlice sp_packet_get_payload(struct Packet */*notnull*/ packet); struct ByteSlice sp_packet_get_payload(struct Packet */*notnull*/ packet);
@ -2010,11 +1953,9 @@ struct ByteSlice sp_packet_get_payload(struct Packet */*notnull*/ packet);
* # Panics * # Panics
* *
* - if the buffer is not big enough to hold header+payload. * - if the buffer is not big enough to hold header+payload.
*
* This function is part of the sp_packet module.
*/ */
size_t sp_packet_serialize_to(struct Packet */*notnull*/ packet, void sp_packet_serialize_to(struct Packet */*notnull*/ packet,
struct ByteSlice buffer); struct ByteSlice buffer);
/** /**
* Sets the value of field `header` of the [`servicepoint::Packet`]. * Sets the value of field `header` of the [`servicepoint::Packet`].
@ -2028,8 +1969,6 @@ void sp_packet_set_header(struct Packet */*notnull*/ instance,
* Sets the payload of the provided packet to the provided data. * Sets the payload of the provided packet to the provided data.
* *
* This makes previous payload pointers invalid. * This makes previous payload pointers invalid.
*
* This function is part of the sp_packet module.
*/ */
void sp_packet_set_payload(struct Packet */*notnull*/ packet, void sp_packet_set_payload(struct Packet */*notnull*/ packet,
struct ByteSlice data); struct ByteSlice data);
@ -2038,8 +1977,6 @@ void sp_packet_set_payload(struct Packet */*notnull*/ packet,
* Tries to load a [Packet] from the passed array with the specified length. * 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 * returns: NULL in case of an error, pointer to the allocated packet otherwise
*
* This function is part of the sp_packet module.
*/ */
struct Packet *sp_packet_try_load(struct ByteSlice data); struct Packet *sp_packet_try_load(struct ByteSlice data);
@ -2047,8 +1984,6 @@ struct Packet *sp_packet_try_load(struct ByteSlice data);
* Converts u16 into [CommandCode]. * Converts u16 into [CommandCode].
* *
* If the provided value is not valid, false is returned and result is not changed. * If the provided value is not valid, false is returned and result is not changed.
*
* This function is part of the sp module.
*/ */
bool sp_u16_to_command_code(uint16_t code, bool sp_u16_to_command_code(uint16_t code,
CommandCode *result); CommandCode *result);
@ -2072,8 +2007,6 @@ void sp_udp_free(struct UdpSocket */*notnull*/ instance);
* if (connection != NULL) * if (connection != NULL)
* sp_udp_send_command(connection, sp_command_clear()); * sp_udp_send_command(connection, sp_command_clear());
* ``` * ```
*
* This function is part of the sp_udp module.
*/ */
struct UdpSocket *sp_udp_open(char */*notnull*/ host); struct UdpSocket *sp_udp_open(char */*notnull*/ host);
@ -2089,8 +2022,6 @@ struct UdpSocket *sp_udp_open(char */*notnull*/ host);
* if (connection != NULL) * if (connection != NULL)
* sp_udp_send_command(connection, sp_command_clear()); * sp_udp_send_command(connection, sp_command_clear());
* ``` * ```
*
* This function is part of the sp_udp module.
*/ */
struct UdpSocket *sp_udp_open_ipv4(uint8_t ip1, struct UdpSocket *sp_udp_open_ipv4(uint8_t ip1,
uint8_t ip2, uint8_t ip2,
@ -2110,8 +2041,6 @@ struct UdpSocket *sp_udp_open_ipv4(uint8_t ip1,
* ```C * ```C
* sp_udp_send_command(connection, sp_command_brightness(5)); * sp_udp_send_command(connection, sp_command_brightness(5));
* ``` * ```
*
* This function is part of the sp_udp module.
*/ */
bool sp_udp_send_command(struct UdpSocket */*notnull*/ connection, bool sp_udp_send_command(struct UdpSocket */*notnull*/ connection,
struct Command command); struct Command command);
@ -2126,8 +2055,6 @@ bool sp_udp_send_command(struct UdpSocket */*notnull*/ connection,
* ```C * ```C
* sp_udp_send_header(connection, sp_command_brightness(5)); * sp_udp_send_header(connection, sp_command_brightness(5));
* ``` * ```
*
* This function is part of the sp_udp module.
*/ */
bool sp_udp_send_header(struct UdpSocket */*notnull*/ udp_connection, bool sp_udp_send_header(struct UdpSocket */*notnull*/ udp_connection,
struct Header header); struct Header header);
@ -2138,8 +2065,6 @@ bool sp_udp_send_header(struct UdpSocket */*notnull*/ udp_connection,
* The passed `packet` gets consumed. * The passed `packet` gets consumed.
* *
* returns: true in case of success * returns: true in case of success
*
* This function is part of the sp_udp module.
*/ */
bool sp_udp_send_packet(struct UdpSocket */*notnull*/ connection, bool sp_udp_send_packet(struct UdpSocket */*notnull*/ connection,
struct Packet */*notnull*/ packet); struct Packet */*notnull*/ packet);

View file

@ -1,22 +1,12 @@
use crate::{ use crate::{
commands::wrap_origin_accessors,
macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions},
mem::{heap_move_nonnull, heap_move_ok, heap_remove}, mem::{heap_move_nonnull, heap_move_ok, heap_remove},
}; };
use servicepoint::{Bitmap, BitmapCommand, CompressionCode, Origin, Packet}; use servicepoint::{Bitmap, BitmapCommand, CompressionCode, Origin, Packet};
use std::ptr::NonNull; use std::ptr::NonNull;
wrap_clone!(sp_cmd_bitmap::BitmapCommand);
wrap_free!(sp_cmd_bitmap::BitmapCommand);
wrap_fields!(sp_cmd_bitmap::BitmapCommand;
prop bitmap: Bitmap { mut get(); move set(value); };
prop compression: CompressionCode { get(); set(value); };
);
wrap_origin_accessors!(sp_cmd_bitmap::BitmapCommand);
wrap_functions!(sp_cmd_bitmap; wrap_functions!(sp_cmd_bitmap;
/// Sets a window of pixels to the specified values. /// Sets a window of pixels to the specified values.
/// ///
/// The passed [Bitmap] gets consumed. /// The passed [Bitmap] gets consumed.
@ -53,4 +43,74 @@ wrap_functions!(sp_cmd_bitmap;
) -> *mut Packet { ) -> *mut Packet {
heap_move_ok(unsafe { heap_remove(command) }.try_into()) heap_move_ok(unsafe { heap_remove(command) }.try_into())
} }
); );
wrap_clone!(sp_cmd_bitmap::BitmapCommand);
wrap_free!(sp_cmd_bitmap::BitmapCommand);
wrap_fields!(
sp_cmd_bitmap::BitmapCommand;
//prop bitmap: NonNull<Bitmap> {
// get() {
// return NonNull::from(bitmap);
// };
// set(value) {
// return unsafe { heap_remove(value) };
// };
//};
prop compression: CompressionCode {
get();
set(value);
};
);
/// Returns a pointer to the provided `BitmapCommand`.
///
/// # Safety
///
/// - The returned bitmap inherits the lifetime of the command in which it is contained.
/// - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command.
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitmap_get(
mut command: NonNull<BitmapCommand>,
) -> NonNull<Bitmap> {
unsafe { NonNull::from(&mut (command.as_mut().bitmap)) }
}
/// Moves the provided [Bitmap] to be contained in the [BitmapCommand].
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitmap_set(
mut command: NonNull<BitmapCommand>,
bitmap: NonNull<Bitmap>,
) {
unsafe {
command.as_mut().bitmap = heap_remove(bitmap);
}
}
/// Reads the origin field of the [BitmapCommand].
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitmap_get_origin(
command: NonNull<BitmapCommand>,
origin_x: NonNull<usize>,
origin_y: NonNull<usize>,
) {
unsafe {
let origin = &command.as_ref().origin;
*origin_x.as_ptr() = origin.x;
*origin_y.as_ptr() = origin.y;
}
}
/// Overwrites the origin field of the [BitmapCommand].
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitmap_set_origin(
mut command: NonNull<BitmapCommand>,
origin_x: usize,
origin_y: usize,
) {
unsafe {
command.as_mut().origin = Origin::new(origin_x, origin_y);
}
}

View file

@ -8,16 +8,6 @@ use servicepoint::{
}; };
use std::ptr::NonNull; use std::ptr::NonNull;
wrap_clone!(sp_cmd_bitvec::BitVecCommand);
wrap_free!(sp_cmd_bitvec::BitVecCommand);
wrap_fields!(sp_cmd_bitvec::BitVecCommand;
prop bitvec: DisplayBitVec { mut get(); move set(value); };
prop offset: Offset { get(); set(value); };
prop operation: BinaryOperation { get(); set(value); };
prop compression: CompressionCode { get(); set(value); };
);
wrap_functions!(sp_cmd_bitvec; wrap_functions!(sp_cmd_bitvec;
/// Set pixel data starting at the pixel offset on screen. /// Set pixel data starting at the pixel offset on screen.
@ -56,3 +46,41 @@ wrap_functions!(sp_cmd_bitvec;
} }
); );
wrap_clone!(sp_cmd_bitvec::BitVecCommand);
wrap_free!(sp_cmd_bitvec::BitVecCommand);
wrap_fields!(
sp_cmd_bitvec::BitVecCommand;
prop offset: Offset {
get();
set(value);
};
prop operation: BinaryOperation {
get();
set(value);
};
prop compression: CompressionCode {
get();
set(value);
};
);
/// Returns a pointer to the [BitVec] contained in the [BitVecCommand].
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitvec_get(
mut command: NonNull<BitVecCommand>,
) -> *mut DisplayBitVec {
unsafe { &mut command.as_mut().bitvec }
}
/// Moves the provided [BitVec] to be contained in the [BitVecCommand].
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitvec_set(
mut command: NonNull<BitVecCommand>,
bitvec: NonNull<DisplayBitVec>,
) {
unsafe {
command.as_mut().bitvec = heap_remove(bitvec);
}
}

View file

@ -1,20 +1,10 @@
use crate::{ use crate::{
commands::wrap_origin_accessors, macros::{wrap_clone, wrap_free, wrap_functions},
macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions},
mem::{heap_move_nonnull, heap_move_ok, heap_remove}, mem::{heap_move_nonnull, heap_move_ok, heap_remove},
}; };
use servicepoint::{BrightnessGrid, BrightnessGridCommand, Origin, Packet}; use servicepoint::{BrightnessGrid, BrightnessGridCommand, Origin, Packet};
use std::ptr::NonNull; use std::ptr::NonNull;
wrap_clone!(sp_cmd_brightness_grid::BrightnessGridCommand);
wrap_free!(sp_cmd_brightness_grid::BrightnessGridCommand);
wrap_fields!(sp_cmd_brightness_grid::BrightnessGridCommand;
prop grid: BrightnessGrid { mut get(); move set(grid); };
);
wrap_origin_accessors!(sp_cmd_brightness_grid::BrightnessGridCommand);
wrap_functions!(sp_cmd_brightness_grid; wrap_functions!(sp_cmd_brightness_grid;
/// Set the brightness of individual tiles in a rectangular area of the display. /// Set the brightness of individual tiles in a rectangular area of the display.
@ -51,3 +41,51 @@ wrap_functions!(sp_cmd_brightness_grid;
} }
); );
wrap_clone!(sp_cmd_brightness_grid::BrightnessGridCommand);
wrap_free!(sp_cmd_brightness_grid::BrightnessGridCommand);
/// Moves the provided [BrightnessGrid] to be contained in the [BrightnessGridCommand].
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_brightness_grid_set(
mut command: NonNull<BrightnessGridCommand>,
grid: NonNull<BrightnessGrid>,
) {
unsafe {
command.as_mut().grid = heap_remove(grid);
}
}
/// Returns a pointer to the [BrightnessGrid] contained in the [BrightnessGridCommand].
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_brightness_grid_get(
mut command: NonNull<BrightnessGridCommand>,
) -> *mut BrightnessGrid {
unsafe { &mut command.as_mut().grid }
}
/// Overwrites the origin field of the [BrightnessGridCommand].
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_brightness_grid_get_origin(
command: NonNull<BrightnessGridCommand>,
origin_x: NonNull<usize>,
origin_y: NonNull<usize>,
) {
unsafe {
let origin = &command.as_ref().origin;
*origin_x.as_ptr() = origin.x;
*origin_y.as_ptr() = origin.y;
}
}
/// Reads the origin field of the [BrightnessGridCommand].
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_brightness_grid_set_origin(
mut command: NonNull<BrightnessGridCommand>,
origin_x: usize,
origin_y: usize,
) {
unsafe {
command.as_mut().origin = Origin::new(origin_x, origin_y);
}
}

View file

@ -5,33 +5,39 @@ use crate::{
use servicepoint::{ClearCommand, FadeOutCommand, HardResetCommand}; use servicepoint::{ClearCommand, FadeOutCommand, HardResetCommand};
use std::ptr::NonNull; use std::ptr::NonNull;
macro_rules! wrap_cc_only { wrap_functions!(sp_cmd_clear;
($prefix:ident :: $typ:ident ; $(#[$meta:meta])*) => {
wrap_functions!($prefix;
$(#[$meta])*
///
#[doc = concat!(" Returns: a new [`",stringify!($typ),"`] instance.")]
fn new() -> NonNull<$typ> {
heap_move_nonnull($typ)
}
);
wrap_free!($prefix :: $typ);
};
}
wrap_cc_only!(sp_cmd_clear::ClearCommand;
/// Set all pixels to the off state. /// Set all pixels to the off state.
/// ///
/// Does not affect brightness. /// Does not affect brightness.
///
/// Returns: a new [ClearCommand] instance.
fn new() -> NonNull<ClearCommand> {
heap_move_nonnull(ClearCommand)
}
); );
wrap_cc_only!(sp_cmd_hard_reset::HardResetCommand; wrap_free!(sp_cmd_clear::ClearCommand);
wrap_functions!(sp_cmd_hard_reset;
/// Kills the udp daemon on the display, which usually results in a restart. /// Kills the udp daemon on the display, which usually results in a restart.
/// ///
/// Please do not send this in your normal program flow. /// Please do not send this in your normal program flow.
///
/// Returns: a new [HardResetCommand] instance.
fn new() -> NonNull<HardResetCommand> {
heap_move_nonnull(HardResetCommand)
}
); );
wrap_cc_only!(sp_cmd_fade_out::FadeOutCommand; wrap_free!(sp_cmd_hard_reset::HardResetCommand);
wrap_functions!(sp_cmd_fade_out;
/// A yet-to-be-tested command. /// A yet-to-be-tested command.
///
/// Returns: a new [FadeOutCommand] instance.
fn new() -> NonNull<FadeOutCommand> {
heap_move_nonnull(FadeOutCommand)
}
); );
wrap_free!(sp_cmd_fade_out::FadeOutCommand);

View file

@ -1,20 +1,10 @@
use crate::{ use crate::{
commands::wrap_origin_accessors, macros::{wrap_clone, wrap_free, wrap_functions},
macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions},
mem::{heap_move_nonnull, heap_move_ok, heap_remove}, mem::{heap_move_nonnull, heap_move_ok, heap_remove},
}; };
use servicepoint::{CharGrid, CharGridCommand, Origin, Packet}; use servicepoint::{CharGrid, CharGridCommand, Origin, Packet};
use std::ptr::NonNull; use std::ptr::NonNull;
wrap_clone!(sp_cmd_char_grid::CharGridCommand);
wrap_free!(sp_cmd_char_grid::CharGridCommand);
wrap_fields!(sp_cmd_char_grid::CharGridCommand;
prop grid: CharGrid { mut get(); move set(grid); };
);
wrap_origin_accessors!(sp_cmd_char_grid::CharGridCommand);
wrap_functions!(sp_cmd_char_grid; wrap_functions!(sp_cmd_char_grid;
/// Show UTF-8 encoded text on the screen. /// Show UTF-8 encoded text on the screen.
@ -51,3 +41,51 @@ wrap_functions!(sp_cmd_char_grid;
} }
); );
wrap_clone!(sp_cmd_char_grid::CharGridCommand);
wrap_free!(sp_cmd_char_grid::CharGridCommand);
/// Moves the provided [CharGrid] to be contained in the [CharGridCommand].
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_char_grid_set(
mut command: NonNull<CharGridCommand>,
grid: NonNull<CharGrid>,
) {
unsafe {
command.as_mut().grid = heap_remove(grid);
}
}
/// Returns a pointer to the [CharGrid] contained in the [CharGridCommand].
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_char_grid_get(
mut command: NonNull<CharGridCommand>,
) -> NonNull<CharGrid> {
unsafe { NonNull::from(&mut command.as_mut().grid) }
}
/// Reads the origin field of the [CharGridCommand].
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_char_grid_get_origin(
command: NonNull<CharGridCommand>,
origin_x: NonNull<usize>,
origin_y: NonNull<usize>,
) {
unsafe {
let origin = &command.as_ref().origin;
*origin_x.as_ptr() = origin.x;
*origin_y.as_ptr() = origin.y;
}
}
/// Overwrites the origin field of the [CharGridCommand].
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_char_grid_set_origin(
mut command: NonNull<CharGridCommand>,
origin_x: usize,
origin_y: usize,
) {
unsafe {
command.as_mut().origin = Origin::new(origin_x, origin_y);
}
}

View file

@ -1,20 +1,10 @@
use crate::{ use crate::{
commands::wrap_origin_accessors, macros::{wrap_clone, wrap_free, wrap_functions},
macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions},
mem::{heap_move_nonnull, heap_move_ok, heap_remove}, mem::{heap_move_nonnull, heap_move_ok, heap_remove},
}; };
use servicepoint::{Cp437Grid, Cp437GridCommand, Origin, Packet}; use servicepoint::{Cp437Grid, Cp437GridCommand, Origin, Packet};
use std::ptr::NonNull; use std::ptr::NonNull;
wrap_clone!(sp_cmd_cp437_grid::Cp437GridCommand);
wrap_free!(sp_cmd_cp437_grid::Cp437GridCommand);
wrap_fields!(sp_cmd_cp437_grid::Cp437GridCommand;
prop grid: Cp437Grid { mut get(); move set(grid); };
);
wrap_origin_accessors!(sp_cmd_cp437_grid::Cp437GridCommand);
wrap_functions!(sp_cmd_cp437_grid; wrap_functions!(sp_cmd_cp437_grid;
/// Show text on the screen. /// Show text on the screen.
@ -51,3 +41,62 @@ wrap_functions!(sp_cmd_cp437_grid;
} }
); );
wrap_clone!(sp_cmd_cp437_grid::Cp437GridCommand);
wrap_free!(sp_cmd_cp437_grid::Cp437GridCommand);
/// Moves the provided bitmap into the provided command.
///
/// This drops the previously contained [Cp437Grid].
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_cp437_grid_set(
mut command: NonNull<Cp437GridCommand>,
grid: NonNull<Cp437Grid>,
) {
unsafe {
command.as_mut().grid = heap_remove(grid);
}
}
/// Show text on the screen.
///
/// The text is sent in the form of a 2D grid of [CP-437] encoded characters.
/// For sending UTF-8 encoded characters, see [servicepoint::CharGridCommand].
///
/// [CP-437]: https://en.wikipedia.org/wiki/Code_page_437
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_cp437_grid_get(
mut command: NonNull<Cp437GridCommand>,
) -> *mut Cp437Grid {
unsafe { &mut command.as_mut().grid }
}
/// Gets the origin field of the [Cp437GridCommand].
///
/// Rust equivalent: `cp437_command.origin`
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_cp437_grid_get_origin(
command: NonNull<Cp437GridCommand>,
origin_x: NonNull<usize>,
origin_y: NonNull<usize>,
) {
unsafe {
let origin = &command.as_ref().origin;
*origin_x.as_ptr() = origin.x;
*origin_y.as_ptr() = origin.y;
}
}
/// Sets the origin field of the [Cp437GridCommand].
///
/// Rust equivalent: `cp437_command.origin = Origin::new(origin_x, origin_y)`
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_cp437_grid_set_origin(
mut command: NonNull<Cp437GridCommand>,
origin_x: usize,
origin_y: usize,
) {
unsafe {
command.as_mut().origin = Origin::new(origin_x, origin_y);
}
}

View file

@ -1,9 +1,6 @@
use crate::{ use crate::mem::{
macros::wrap_functions, heap_clone, heap_drop, heap_move, heap_move_nonnull, heap_move_ok,
mem::{ heap_remove,
heap_clone, heap_drop, heap_move, heap_move_nonnull, heap_move_ok,
heap_remove,
},
}; };
use servicepoint::{ use servicepoint::{
BitVecCommand, BitmapCommand, BrightnessGridCommand, CharGridCommand, BitVecCommand, BitmapCommand, BrightnessGridCommand, CharGridCommand,
@ -69,233 +66,233 @@ impl SPCommand {
}; };
} }
wrap_functions!(sp_cmd_generic; /// Tries to turn a [Packet] into a [SPCommand].
///
/// The packet is dropped in the process.
///
/// Returns: pointer to new [SPCommand] instance or NULL if parsing failed.
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_generic_try_from_packet(
packet: NonNull<Packet>,
) -> SPCommand {
let packet = *unsafe { Box::from_raw(packet.as_ptr()) };
servicepoint::TypedCommand::try_from(packet)
.map(|value| match value {
TypedCommand::Clear(clear) => SPCommand {
tag: CommandTag::Clear,
data: CommandUnion {
clear: heap_move_nonnull(clear),
},
},
TypedCommand::CharGrid(char_grid) => SPCommand {
tag: CommandTag::CharGrid,
data: CommandUnion {
char_grid: heap_move_nonnull(char_grid),
},
},
TypedCommand::Cp437Grid(cp437_grid) => SPCommand {
tag: CommandTag::Cp437Grid,
data: CommandUnion {
cp437_grid: heap_move_nonnull(cp437_grid),
},
},
TypedCommand::Bitmap(bitmap) => SPCommand {
tag: CommandTag::Bitmap,
data: CommandUnion {
bitmap: heap_move_nonnull(bitmap),
},
},
TypedCommand::Brightness(global_brightness) => SPCommand {
tag: CommandTag::GlobalBrightness,
data: CommandUnion {
global_brightness: heap_move_nonnull(global_brightness),
},
},
TypedCommand::BrightnessGrid(brightness_grid) => SPCommand {
tag: CommandTag::BrightnessGrid,
data: CommandUnion {
brightness_grid: heap_move_nonnull(brightness_grid),
},
},
TypedCommand::BitVec(bitvec) => SPCommand {
tag: CommandTag::BitVec,
data: CommandUnion {
bitvec: heap_move_nonnull(bitvec),
},
},
TypedCommand::HardReset(hard_reset) => SPCommand {
tag: CommandTag::HardReset,
data: CommandUnion {
hard_reset: heap_move_nonnull(hard_reset),
},
},
TypedCommand::FadeOut(fade_out) => SPCommand {
tag: CommandTag::FadeOut,
data: CommandUnion {
fade_out: heap_move_nonnull(fade_out),
},
},
#[allow(deprecated)]
TypedCommand::BitmapLegacy(bitmap_legacy) => SPCommand {
tag: CommandTag::BitmapLegacy,
data: CommandUnion {
bitmap_legacy: heap_move_nonnull(bitmap_legacy),
},
},
})
.unwrap_or_else(move |_| SPCommand {
tag: CommandTag::Invalid,
data: CommandUnion { null: null_mut() },
})
}
/// Tries to turn a [Packet] into a [SPCommand]. /// Clones an [SPCommand] instance.
/// ///
/// The packet is dropped in the process. /// returns: a new [SPCommand] instance.
/// #[no_mangle]
/// Returns: pointer to new [SPCommand] instance or NULL if parsing failed. pub unsafe extern "C" fn sp_cmd_generic_clone(command: SPCommand) -> SPCommand {
fn try_from_packet( unsafe {
packet: NonNull<Packet>,
) -> SPCommand {
let packet = *unsafe { Box::from_raw(packet.as_ptr()) };
servicepoint::TypedCommand::try_from(packet)
.map(|value| match value {
TypedCommand::Clear(clear) => SPCommand {
tag: CommandTag::Clear,
data: CommandUnion {
clear: heap_move_nonnull(clear),
},
},
TypedCommand::CharGrid(char_grid) => SPCommand {
tag: CommandTag::CharGrid,
data: CommandUnion {
char_grid: heap_move_nonnull(char_grid),
},
},
TypedCommand::Cp437Grid(cp437_grid) => SPCommand {
tag: CommandTag::Cp437Grid,
data: CommandUnion {
cp437_grid: heap_move_nonnull(cp437_grid),
},
},
TypedCommand::Bitmap(bitmap) => SPCommand {
tag: CommandTag::Bitmap,
data: CommandUnion {
bitmap: heap_move_nonnull(bitmap),
},
},
TypedCommand::Brightness(global_brightness) => SPCommand {
tag: CommandTag::GlobalBrightness,
data: CommandUnion {
global_brightness: heap_move_nonnull(global_brightness),
},
},
TypedCommand::BrightnessGrid(brightness_grid) => SPCommand {
tag: CommandTag::BrightnessGrid,
data: CommandUnion {
brightness_grid: heap_move_nonnull(brightness_grid),
},
},
TypedCommand::BitVec(bitvec) => SPCommand {
tag: CommandTag::BitVec,
data: CommandUnion {
bitvec: heap_move_nonnull(bitvec),
},
},
TypedCommand::HardReset(hard_reset) => SPCommand {
tag: CommandTag::HardReset,
data: CommandUnion {
hard_reset: heap_move_nonnull(hard_reset),
},
},
TypedCommand::FadeOut(fade_out) => SPCommand {
tag: CommandTag::FadeOut,
data: CommandUnion {
fade_out: heap_move_nonnull(fade_out),
},
},
#[allow(deprecated)]
TypedCommand::BitmapLegacy(bitmap_legacy) => SPCommand {
tag: CommandTag::BitmapLegacy,
data: CommandUnion {
bitmap_legacy: heap_move_nonnull(bitmap_legacy),
},
},
})
.unwrap_or_else(move |_| SPCommand {
tag: CommandTag::Invalid,
data: CommandUnion { null: null_mut() },
})
}
/// Clones an [SPCommand] instance.
///
/// returns: a new [SPCommand] instance.
fn clone(command: SPCommand) -> SPCommand {
unsafe {
match command.tag {
CommandTag::Clear => SPCommand {
tag: CommandTag::Clear,
data: CommandUnion {
clear: heap_clone(command.data.clear),
},
},
CommandTag::CharGrid => SPCommand {
tag: CommandTag::CharGrid,
data: CommandUnion {
char_grid: heap_clone(command.data.char_grid),
},
},
CommandTag::Cp437Grid => SPCommand {
tag: CommandTag::Cp437Grid,
data: CommandUnion {
cp437_grid: heap_clone(command.data.cp437_grid),
},
},
CommandTag::Bitmap => SPCommand {
tag: CommandTag::Bitmap,
data: CommandUnion {
bitmap: heap_clone(command.data.bitmap),
},
},
CommandTag::GlobalBrightness => SPCommand {
tag: CommandTag::GlobalBrightness,
data: CommandUnion {
global_brightness: heap_clone(
command.data.global_brightness,
),
},
},
CommandTag::BrightnessGrid => SPCommand {
tag: CommandTag::BrightnessGrid,
data: CommandUnion {
brightness_grid: heap_clone(command.data.brightness_grid),
},
},
CommandTag::BitVec => SPCommand {
tag: CommandTag::BitVec,
data: CommandUnion {
bitvec: heap_clone(command.data.bitvec),
},
},
CommandTag::HardReset => SPCommand {
tag: CommandTag::HardReset,
data: CommandUnion {
hard_reset: heap_clone(command.data.hard_reset),
},
},
CommandTag::FadeOut => SPCommand {
tag: CommandTag::FadeOut,
data: CommandUnion {
fade_out: heap_clone(command.data.fade_out),
},
},
#[allow(deprecated)]
CommandTag::BitmapLegacy => SPCommand {
tag: CommandTag::BitmapLegacy,
data: CommandUnion {
bitmap_legacy: heap_clone(command.data.bitmap_legacy),
},
},
CommandTag::Invalid => SPCommand::INVALID,
}
}
}
/// Deallocates an [SPCommand].
///
/// Commands with an invalid `tag` do not have to be freed as the `data` pointer should be null.
///
/// # Examples
///
/// ```C
/// SPCommand c = sp_cmd_clear_into_generic(sp_cmd_clear_new());
/// sp_command_free(c);
/// ```
fn free(command: SPCommand) {
unsafe {
match command.tag {
CommandTag::Invalid => (),
CommandTag::Bitmap => heap_drop(command.data.bitmap),
CommandTag::BitVec => heap_drop(command.data.bitvec),
CommandTag::BrightnessGrid => {
heap_drop(command.data.brightness_grid)
}
CommandTag::CharGrid => heap_drop(command.data.char_grid),
CommandTag::Cp437Grid => heap_drop(command.data.cp437_grid),
CommandTag::GlobalBrightness => {
heap_drop(command.data.global_brightness)
}
CommandTag::Clear => heap_drop(command.data.clear),
CommandTag::HardReset => heap_drop(command.data.hard_reset),
CommandTag::FadeOut => heap_drop(command.data.fade_out),
CommandTag::BitmapLegacy => heap_drop(command.data.bitmap_legacy),
}
}
}
/// Tries to turn a [SPCommand] into a [Packet].
/// The [SPCommand] gets consumed.
///
/// Returns tag [CommandTag::Invalid] in case of an error.
fn into_packet(
command: SPCommand,
) -> *mut Packet {
match command.tag { match command.tag {
CommandTag::Invalid => null_mut(), CommandTag::Clear => SPCommand {
CommandTag::Bitmap => { tag: CommandTag::Clear,
heap_move_ok(unsafe { heap_remove(command.data.bitmap).try_into() }) data: CommandUnion {
} clear: heap_clone(command.data.clear),
CommandTag::BitVec => { },
heap_move_ok(unsafe { heap_remove(command.data.bitvec).try_into() }) },
} CommandTag::CharGrid => SPCommand {
CommandTag::BrightnessGrid => heap_move_ok(unsafe { tag: CommandTag::CharGrid,
heap_remove(command.data.brightness_grid).try_into() data: CommandUnion {
}), char_grid: heap_clone(command.data.char_grid),
CommandTag::CharGrid => heap_move_ok(unsafe { },
heap_remove(command.data.char_grid).try_into() },
}), CommandTag::Cp437Grid => SPCommand {
CommandTag::Cp437Grid => heap_move_ok(unsafe { tag: CommandTag::Cp437Grid,
heap_remove(command.data.cp437_grid).try_into() data: CommandUnion {
}), cp437_grid: heap_clone(command.data.cp437_grid),
CommandTag::GlobalBrightness => heap_move(unsafe { },
heap_remove(command.data.global_brightness).into() },
}), CommandTag::Bitmap => SPCommand {
CommandTag::Clear => { tag: CommandTag::Bitmap,
heap_move(unsafe { heap_remove(command.data.clear).into() }) data: CommandUnion {
} bitmap: heap_clone(command.data.bitmap),
CommandTag::HardReset => { },
heap_move(unsafe { heap_remove(command.data.hard_reset).into() }) },
} CommandTag::GlobalBrightness => SPCommand {
CommandTag::FadeOut => { tag: CommandTag::GlobalBrightness,
heap_move(unsafe { heap_remove(command.data.fade_out).into() }) data: CommandUnion {
} global_brightness: heap_clone(
CommandTag::BitmapLegacy => { command.data.global_brightness,
heap_move(unsafe { heap_remove(command.data.bitmap_legacy).into() }) ),
} },
},
CommandTag::BrightnessGrid => SPCommand {
tag: CommandTag::BrightnessGrid,
data: CommandUnion {
brightness_grid: heap_clone(command.data.brightness_grid),
},
},
CommandTag::BitVec => SPCommand {
tag: CommandTag::BitVec,
data: CommandUnion {
bitvec: heap_clone(command.data.bitvec),
},
},
CommandTag::HardReset => SPCommand {
tag: CommandTag::HardReset,
data: CommandUnion {
hard_reset: heap_clone(command.data.hard_reset),
},
},
CommandTag::FadeOut => SPCommand {
tag: CommandTag::FadeOut,
data: CommandUnion {
fade_out: heap_clone(command.data.fade_out),
},
},
#[allow(deprecated)]
CommandTag::BitmapLegacy => SPCommand {
tag: CommandTag::BitmapLegacy,
data: CommandUnion {
bitmap_legacy: heap_clone(command.data.bitmap_legacy),
},
},
CommandTag::Invalid => SPCommand::INVALID,
} }
} }
}
); /// Deallocates an [SPCommand].
///
/// Commands with an invalid `tag` do not have to be freed as the `data` pointer should be null.
///
/// # Examples
///
/// ```C
/// SPCommand c = sp_cmd_clear_into_generic(sp_cmd_clear_new());
/// sp_command_free(c);
/// ```
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_generic_free(command: SPCommand) {
unsafe {
match command.tag {
CommandTag::Invalid => (),
CommandTag::Bitmap => heap_drop(command.data.bitmap),
CommandTag::BitVec => heap_drop(command.data.bitvec),
CommandTag::BrightnessGrid => {
heap_drop(command.data.brightness_grid)
}
CommandTag::CharGrid => heap_drop(command.data.char_grid),
CommandTag::Cp437Grid => heap_drop(command.data.cp437_grid),
CommandTag::GlobalBrightness => {
heap_drop(command.data.global_brightness)
}
CommandTag::Clear => heap_drop(command.data.clear),
CommandTag::HardReset => heap_drop(command.data.hard_reset),
CommandTag::FadeOut => heap_drop(command.data.fade_out),
CommandTag::BitmapLegacy => heap_drop(command.data.bitmap_legacy),
}
}
}
/// Tries to turn a [SPCommand] into a [Packet].
/// The [SPCommand] gets consumed.
///
/// Returns tag [CommandTag::Invalid] in case of an error.
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_generic_into_packet(
command: SPCommand,
) -> *mut Packet {
match command.tag {
CommandTag::Invalid => null_mut(),
CommandTag::Bitmap => {
heap_move_ok(unsafe { heap_remove(command.data.bitmap).try_into() })
}
CommandTag::BitVec => {
heap_move_ok(unsafe { heap_remove(command.data.bitvec).try_into() })
}
CommandTag::BrightnessGrid => heap_move_ok(unsafe {
heap_remove(command.data.brightness_grid).try_into()
}),
CommandTag::CharGrid => heap_move_ok(unsafe {
heap_remove(command.data.char_grid).try_into()
}),
CommandTag::Cp437Grid => heap_move_ok(unsafe {
heap_remove(command.data.cp437_grid).try_into()
}),
CommandTag::GlobalBrightness => heap_move(unsafe {
heap_remove(command.data.global_brightness).into()
}),
CommandTag::Clear => {
heap_move(unsafe { heap_remove(command.data.clear).into() })
}
CommandTag::HardReset => {
heap_move(unsafe { heap_remove(command.data.hard_reset).into() })
}
CommandTag::FadeOut => {
heap_move(unsafe { heap_remove(command.data.fade_out).into() })
}
CommandTag::BitmapLegacy => {
heap_move(unsafe { heap_remove(command.data.bitmap_legacy).into() })
}
}
}

View file

@ -13,35 +13,3 @@ pub use brightness_grid_command::*;
pub use char_grid_command::*; pub use char_grid_command::*;
pub use cp437_grid_command::*; pub use cp437_grid_command::*;
pub use generic_command::*; pub use generic_command::*;
macro_rules! wrap_origin_accessors {
( $prefix:ident :: $object_type:ty ) => {
$crate::macros::wrap_functions!($prefix;
#[doc = concat!(" Reads the origin field of the [`", stringify!($object_type), "`].")]
fn get_origin(
command: NonNull<$object_type>,
origin_x: NonNull<usize>,
origin_y: NonNull<usize>,
) {
unsafe {
let origin = &command.as_ref().origin;
*origin_x.as_ptr() = origin.x;
*origin_y.as_ptr() = origin.y;
}
}
#[doc = concat!(" Overwrites the origin field of the [`", stringify!($object_type), "`].")]
fn set_origin(
command: NonNull<$object_type>,
origin_x: usize,
origin_y: usize,
) {
unsafe {
$crate::macros::nonnull_as_mut!(command).origin = ::servicepoint::Origin::new(origin_x, origin_y);
}
}
);
};
}
pub(crate) use wrap_origin_accessors;

View file

@ -35,7 +35,7 @@ impl ByteSlice {
unsafe { std::slice::from_raw_parts(self.start, self.length) } unsafe { std::slice::from_raw_parts(self.start, self.length) }
} }
pub(crate) unsafe fn as_slice_mut(&self) -> &mut [u8] { pub(crate) unsafe fn as_slice_mut(&mut self) -> &mut [u8] {
unsafe { std::slice::from_raw_parts_mut(self.start, self.length) } unsafe { std::slice::from_raw_parts_mut(self.start, self.length) }
} }

View file

@ -47,13 +47,10 @@ pub struct DisplayBitVec;
#[cfg(feature = "env_logger")] #[cfg(feature = "env_logger")]
mod feature_env_logger { mod feature_env_logger {
use crate::macros::wrap_functions; /// Call this function at the beginning of main to enable rust logging controlled by the
/// `RUST_LOG` environment variable. See [env_logger](https://docs.rs/env_logger/latest/env_logger/).
wrap_functions!(sp_envlogger; #[no_mangle]
/// Call this function at the beginning of main to enable rust logging controlled by the pub unsafe extern "C" fn init_env_logger() {
/// `RUST_LOG` environment variable. See [env_logger](https://docs.rs/env_logger/latest/env_logger/). env_logger::init();
fn init() { }
env_logger::init();
}
);
} }

View file

@ -28,7 +28,7 @@ macro_rules! nonnull_as_ref {
macro_rules! nonnull_as_mut { macro_rules! nonnull_as_mut {
($ident:ident) => { ($ident:ident) => {
(&mut *$ident.as_ptr()) &mut *$ident.as_ptr()
}; };
} }
@ -84,37 +84,21 @@ macro_rules! wrap_fields {
( (
$prefix:ident :: $object_type:ty; $prefix:ident :: $object_type:ty;
$( $(
prop $prop_name:ident : $prop_type:ty { prop $prop_name:ident : $prop_type:ty {
$( $(
get() $({ get() $({
$(#[$get_meta:meta])* $(#[$get_meta:meta])*
$(return $get_expr:expr;)? $(return $get_expr:expr;)?
})?; })?;
)? )?
$(
$( set($value:ident)
mut get() $({ $({
$(#[$get_mut_meta:meta])* $(#[$set_meta:meta])*
$(return $get_mut_expr:expr;)? $(return $set_expr:expr;)?
})?; })?;
)? )?
};
$(
set($value:ident)
$({
$(#[$set_meta:meta])*
$(return $set_expr:expr;)?
})?;
)?
$(
move set( $set_move_value:ident)
$({
$(#[$set_move_meta:meta])*
$(return $set_move_expr:expr;)?
})?;
)?
};
)+ )+
) => { ) => {
paste::paste! { paste::paste! {
@ -122,15 +106,16 @@ macro_rules! wrap_fields {
$( $(
$( $(
#[doc = concat!(" Gets the value of field `", stringify!($prop_name), #[doc = concat!(" Gets the value of field `", stringify!($prop_name),
"` of the [`servicepoint::", stringify!($object_type),"`].")] "` of the [`servicepoint::",stringify!($object_type),"`].")]
$($( $($(
#[doc = ""] #[doc = ""]
#[$get_meta] #[$get_meta]
)*)? )*)?
fn [<get _ $prop_name>]( fn [<get _ $prop_name>](
instance: ::core::ptr::NonNull<$object_type> instance: NonNull<$object_type>
) -> $prop_type { ) -> $prop_type {
let $prop_name = unsafe { $crate::macros::nonnull_as_ref!(instance).$prop_name }; let instance = unsafe { $crate::macros::nonnull_as_ref!(instance) };
let $prop_name = instance.$prop_name;
$($( $($(
let $prop_name = $get_expr; let $prop_name = $get_expr;
)?)? )?)?
@ -138,27 +123,6 @@ macro_rules! wrap_fields {
} }
)? )?
$(
#[doc = concat!(" Gets a reference to the field `", stringify!($prop_name),
"` of the [`servicepoint::",stringify!($object_type),"`].")]
$($(
#[doc = ""]
#[$get_mut_meta]
)*)?
#[doc = ""]
#[doc = " - The returned reference inherits the lifetime of object in which it is contained."]
#[doc = " - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command."]
fn [<get _ $prop_name _mut>](
instance: ::core::ptr::NonNull<$object_type>
) -> ::core::ptr::NonNull<$prop_type> {
let $prop_name = unsafe { &mut $crate::macros::nonnull_as_mut!(instance).$prop_name };
$($(
let $prop_name = $get_mut_expr;
)?)?
return ::core::ptr::NonNull::from($prop_name);
}
)?
$( $(
#[doc = concat!(" Sets the value of field `", stringify!($prop_name), #[doc = concat!(" Sets the value of field `", stringify!($prop_name),
"` of the [`servicepoint::",stringify!($object_type),"`].")] "` of the [`servicepoint::",stringify!($object_type),"`].")]
@ -167,7 +131,7 @@ macro_rules! wrap_fields {
#[$set_meta] #[$set_meta]
)*)? )*)?
fn [<set _ $prop_name>]( fn [<set _ $prop_name>](
instance: ::core::ptr::NonNull<$object_type>, instance: NonNull<$object_type>,
value: $prop_type, value: $prop_type,
) { ) {
let instance = unsafe { $crate::macros::nonnull_as_mut!(instance) }; let instance = unsafe { $crate::macros::nonnull_as_mut!(instance) };
@ -178,29 +142,6 @@ macro_rules! wrap_fields {
instance.$prop_name = value; instance.$prop_name = value;
} }
)? )?
$(
#[doc = concat!(" Sets the value of field `", stringify!($prop_name),
"` of the [`servicepoint::",stringify!($object_type),"`].")]
#[doc = concat!(" The provided value is moved into the instance, ",
"potentially invalidating previously taken references.")]
$($(
#[doc = ""]
#[$set_move_meta]
)*)?
fn [<set _ $prop_name>](
instance: ::core::ptr::NonNull<$object_type>,
value: NonNull<$prop_type>,
) {
let instance = unsafe { $crate::macros::nonnull_as_mut!(instance) };
let value = unsafe { $crate::mem::heap_remove(value) };
$($(
let $set_move_value = value;
let value = $set_move_expr;
)?)?
instance.$prop_name = value;
}
)?
)+ )+
); );
} }

View file

@ -1,72 +1,95 @@
use crate::{ use crate::{
containers::ByteSlice, containers::ByteSlice,
macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, macros::{wrap_clone, wrap_fields, wrap_free},
mem::{heap_move_nonnull, heap_move_ok}, mem::{heap_move_nonnull, heap_move_ok},
}; };
use servicepoint::{CommandCode, Header, Packet}; use servicepoint::{CommandCode, Header, Packet};
use std::ptr::NonNull; use std::ptr::NonNull;
wrap_functions!(sp_packet; /// Tries to load a [Packet] from the passed array with the specified length.
///
/// returns: NULL in case of an error, pointer to the allocated packet otherwise
#[no_mangle]
pub unsafe extern "C" fn sp_packet_try_load(data: ByteSlice) -> *mut Packet {
let data = unsafe { data.as_slice() };
heap_move_ok(servicepoint::Packet::try_from(data))
}
/// Tries to load a [Packet] from the passed array with the specified length. /// Creates a raw [Packet] from parts.
/// ///
/// returns: NULL in case of an error, pointer to the allocated packet otherwise /// returns: new instance. Will never return null.
fn try_load(data: ByteSlice) -> *mut Packet { #[no_mangle]
let data = unsafe { data.as_slice() }; pub unsafe extern "C" fn sp_packet_from_parts(
heap_move_ok(servicepoint::Packet::try_from(data)) header: Header,
payload: ByteSlice,
) -> NonNull<Packet> {
let payload = if payload == ByteSlice::INVALID {
None
} else {
Some(Vec::from(unsafe { payload.as_slice() }))
};
heap_move_nonnull(Packet { header, payload })
}
/// Returns a pointer to the header field of the provided packet.
///
/// The returned header can be changed and will be valid for the lifetime of the packet.
#[no_mangle]
pub unsafe extern "C" fn sp_packet_get_header_mut(
packet: NonNull<Packet>,
) -> NonNull<Header> {
NonNull::from(unsafe { &mut (*packet.as_ptr()).header })
}
/// Returns a pointer to the current payload of the provided packet.
///
/// Returns an [ByteSlice::INVALID] instance in case the packet does not have any payload.
///
/// The returned memory can be changed and will be valid until a new payload is set.
#[no_mangle]
pub unsafe extern "C" fn sp_packet_get_payload(
packet: NonNull<Packet>,
) -> ByteSlice {
unsafe {
match &mut (*packet.as_ptr()).payload {
None => ByteSlice::INVALID,
Some(payload) => ByteSlice::from_slice(payload),
}
} }
}
/// Creates a raw [Packet] from parts. /// Sets the payload of the provided packet to the provided data.
/// ///
/// returns: new instance. Will never return null. /// This makes previous payload pointers invalid.
fn from_parts(header: Header, payload: ByteSlice) -> NonNull<Packet> { #[no_mangle]
let payload = if payload == ByteSlice::INVALID { pub unsafe extern "C" fn sp_packet_set_payload(
packet: NonNull<Packet>,
data: ByteSlice,
) {
unsafe {
(*packet.as_ptr()).payload = if data == ByteSlice::INVALID {
None None
} else { } else {
Some(Vec::from(unsafe { payload.as_slice() })) Some(data.as_slice().to_vec())
};
heap_move_nonnull(Packet { header, payload })
}
/// Returns a pointer to the current payload of the provided packet.
///
/// Returns an [ByteSlice::INVALID] instance in case the packet does not have any payload.
///
/// The returned memory can be changed and will be valid until a new payload is set.
fn get_payload(packet: NonNull<Packet>) -> ByteSlice {
unsafe {
match &mut (*packet.as_ptr()).payload {
None => ByteSlice::INVALID,
Some(payload) => ByteSlice::from_slice(payload),
}
} }
} }
}
/// Sets the payload of the provided packet to the provided data. /// Serialize the packet into the provided buffer.
/// ///
/// This makes previous payload pointers invalid. /// # Panics
fn set_payload(packet: NonNull<Packet>, data: ByteSlice) { ///
unsafe { /// - if the buffer is not big enough to hold header+payload.
(*packet.as_ptr()).payload = if data == ByteSlice::INVALID { #[no_mangle]
None pub unsafe extern "C" fn sp_packet_serialize_to(
} else { packet: NonNull<Packet>,
Some(data.as_slice().to_vec()) mut buffer: ByteSlice,
} ) {
} unsafe {
packet.as_ref().serialize_to(buffer.as_slice_mut());
} }
}
/// Serialize the packet into the provided buffer.
///
/// # Panics
///
/// - if the buffer is not big enough to hold header+payload.
fn serialize_to(packet: NonNull<Packet>, buffer: ByteSlice) -> usize {
unsafe {
packet.as_ref().serialize_to(buffer.as_slice_mut()).unwrap_or(0)
}
}
);
wrap_clone!(sp_packet::Packet); wrap_clone!(sp_packet::Packet);
wrap_free!(sp_packet::Packet); wrap_free!(sp_packet::Packet);
@ -75,29 +98,25 @@ wrap_fields!(
sp_packet::Packet; sp_packet::Packet;
prop header: Header { prop header: Header {
get(); get();
mut get();
set(value); set(value);
}; };
); );
wrap_functions!(sp; /// Converts u16 into [CommandCode].
///
/// Converts u16 into [CommandCode]. /// If the provided value is not valid, false is returned and result is not changed.
/// #[no_mangle]
/// If the provided value is not valid, false is returned and result is not changed. pub unsafe extern "C" fn sp_u16_to_command_code(
fn u16_to_command_code( code: u16,
code: u16, result: *mut CommandCode,
result: *mut CommandCode, ) -> bool {
) -> bool { match CommandCode::try_from(code) {
match CommandCode::try_from(code) { Ok(code) => {
Ok(code) => { unsafe {
unsafe { *result = code;
*result = code;
}
true
} }
Err(_) => false, true
} }
Err(_) => false,
} }
}
);

View file

@ -1,6 +1,6 @@
use crate::{ use crate::{
commands::{CommandTag, SPCommand}, commands::{CommandTag, SPCommand},
macros::{wrap_free, wrap_functions}, macros::wrap_free,
mem::{heap_move_ok, heap_remove}, mem::{heap_move_ok, heap_remove},
}; };
use servicepoint::{Header, Packet, UdpSocketExt}; use servicepoint::{Header, Packet, UdpSocketExt};
@ -10,122 +10,138 @@ use std::{
ptr::NonNull, ptr::NonNull,
}; };
wrap_free!(sp_udp::UdpSocket); /// Creates a new instance of [UdpSocket].
///
/// returns: NULL if connection fails, or connected instance
///
/// # Examples
///
/// ```C
/// UdpSocket connection = sp_udp_open("172.23.42.29:2342");
/// if (connection != NULL)
/// sp_udp_send_command(connection, sp_command_clear());
/// ```
#[no_mangle]
pub unsafe extern "C" fn sp_udp_open(host: NonNull<c_char>) -> *mut UdpSocket {
let host = unsafe { CStr::from_ptr(host.as_ptr()) }
.to_str()
.expect("Bad encoding");
wrap_functions!(sp_udp; heap_move_ok(UdpSocket::bind_connect(host))
}
/// Creates a new instance of [UdpSocket]. /// Creates a new instance of [UdpSocket].
/// ///
/// returns: NULL if connection fails, or connected instance /// returns: NULL if connection fails, or connected instance
/// ///
/// # Examples /// # Examples
/// ///
/// ```C /// ```C
/// UdpSocket connection = sp_udp_open("172.23.42.29:2342"); /// UdpSocket connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342);
/// if (connection != NULL) /// if (connection != NULL)
/// sp_udp_send_command(connection, sp_command_clear()); /// sp_udp_send_command(connection, sp_command_clear());
/// ``` /// ```
fn open(host: NonNull<c_char>) -> *mut UdpSocket { #[no_mangle]
let host = unsafe { CStr::from_ptr(host.as_ptr()) } pub unsafe extern "C" fn sp_udp_open_ipv4(
.to_str() ip1: u8,
.expect("Bad encoding"); ip2: u8,
ip3: u8,
ip4: u8,
port: u16,
) -> *mut UdpSocket {
let addr = SocketAddrV4::new(Ipv4Addr::from([ip1, ip2, ip3, ip4]), port);
heap_move_ok(UdpSocket::bind_connect(addr))
}
heap_move_ok(UdpSocket::bind_connect(host)) /// Sends a [Packet] to the display using the [UdpSocket].
} ///
/// The passed `packet` gets consumed.
///
/// returns: true in case of success
#[no_mangle]
pub unsafe extern "C" fn sp_udp_send_packet(
connection: NonNull<UdpSocket>,
packet: NonNull<Packet>,
) -> bool {
let packet = unsafe { heap_remove(packet) };
unsafe { connection.as_ref().send(&Vec::from(packet)) }.is_ok()
}
/// Creates a new instance of [UdpSocket]. /// Sends a [SPCommand] to the display using the [UdpSocket].
/// ///
/// returns: NULL if connection fails, or connected instance /// The passed `command` gets consumed.
/// ///
/// # Examples /// returns: true in case of success
/// ///
/// ```C /// # Examples
/// UdpSocket connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342); ///
/// if (connection != NULL) /// ```C
/// sp_udp_send_command(connection, sp_command_clear()); /// sp_udp_send_command(connection, sp_command_brightness(5));
/// ``` /// ```
fn open_ipv4(ip1: u8, ip2: u8, ip3: u8, ip4: u8, port: u16) -> *mut UdpSocket { #[no_mangle]
let addr = SocketAddrV4::new(Ipv4Addr::from([ip1, ip2, ip3, ip4]), port); pub unsafe extern "C" fn sp_udp_send_command(
heap_move_ok(UdpSocket::bind_connect(addr)) connection: NonNull<UdpSocket>,
} command: SPCommand,
) -> bool {
/// Sends a [Packet] to the display using the [UdpSocket]. unsafe {
/// match command.tag {
/// The passed `packet` gets consumed. CommandTag::Invalid => return false,
/// CommandTag::Bitmap => connection
/// returns: true in case of success .as_ref()
fn send_packet(connection: NonNull<UdpSocket>, packet: NonNull<Packet>) -> bool { .send_command(heap_remove(command.data.bitmap)),
let packet = unsafe { heap_remove(packet) }; CommandTag::BitVec => connection
unsafe { connection.as_ref().send(&Vec::from(packet)) }.is_ok() .as_ref()
} .send_command(heap_remove(command.data.bitvec)),
CommandTag::BrightnessGrid => connection
/// Sends a [SPCommand] to the display using the [UdpSocket]. .as_ref()
/// .send_command(heap_remove(command.data.brightness_grid)),
/// The passed `command` gets consumed. CommandTag::CharGrid => connection
/// .as_ref()
/// returns: true in case of success .send_command(heap_remove(command.data.char_grid)),
/// CommandTag::Cp437Grid => connection
/// # Examples .as_ref()
/// .send_command(heap_remove(command.data.cp437_grid)),
/// ```C CommandTag::GlobalBrightness => connection
/// sp_udp_send_command(connection, sp_command_brightness(5)); .as_ref()
/// ``` .send_command(heap_remove(command.data.global_brightness)),
fn send_command(connection: NonNull<UdpSocket>, command: SPCommand) -> bool { CommandTag::Clear => connection
unsafe { .as_ref()
match command.tag { .send_command(heap_remove(command.data.clear)),
CommandTag::Invalid => return false, CommandTag::HardReset => connection
CommandTag::Bitmap => connection .as_ref()
.as_ref() .send_command(heap_remove(command.data.hard_reset)),
.send_command(heap_remove(command.data.bitmap)), CommandTag::FadeOut => connection
CommandTag::BitVec => connection .as_ref()
.as_ref() .send_command(heap_remove(command.data.fade_out)),
.send_command(heap_remove(command.data.bitvec)), CommandTag::BitmapLegacy => connection
CommandTag::BrightnessGrid => connection .as_ref()
.as_ref() .send_command(heap_remove(command.data.bitmap_legacy)),
.send_command(heap_remove(command.data.brightness_grid)),
CommandTag::CharGrid => connection
.as_ref()
.send_command(heap_remove(command.data.char_grid)),
CommandTag::Cp437Grid => connection
.as_ref()
.send_command(heap_remove(command.data.cp437_grid)),
CommandTag::GlobalBrightness => connection
.as_ref()
.send_command(heap_remove(command.data.global_brightness)),
CommandTag::Clear => connection
.as_ref()
.send_command(heap_remove(command.data.clear)),
CommandTag::HardReset => connection
.as_ref()
.send_command(heap_remove(command.data.hard_reset)),
CommandTag::FadeOut => connection
.as_ref()
.send_command(heap_remove(command.data.fade_out)),
CommandTag::BitmapLegacy => connection
.as_ref()
.send_command(heap_remove(command.data.bitmap_legacy)),
}
} }
.is_some()
} }
.is_some()
}
/// Sends a [Header] to the display using the [UdpSocket]. /// Sends a [Header] to the display using the [UdpSocket].
/// ///
/// returns: true in case of success /// returns: true in case of success
/// ///
/// # Examples /// # Examples
/// ///
/// ```C /// ```C
/// sp_udp_send_header(connection, sp_command_brightness(5)); /// sp_udp_send_header(connection, sp_command_brightness(5));
/// ``` /// ```
fn send_header(udp_connection: NonNull<UdpSocket>, header: Header) -> bool { #[no_mangle]
let packet = Packet { pub unsafe extern "C" fn sp_udp_send_header(
header, udp_connection: NonNull<UdpSocket>,
payload: None, header: Header,
}; ) -> bool {
unsafe { udp_connection.as_ref() } let packet = Packet {
.send(&Vec::from(packet)) header,
.is_ok() payload: None,
} };
unsafe { udp_connection.as_ref() }
.send(&Vec::from(packet))
.is_ok()
}
); wrap_free!(sp_udp::UdpSocket);