Compare commits
	
		
			No commits in common. "3589a90385b7bf33f165fe8fb663f2798bd523d7" and "b4eab85b199bef044cc33cff20c9bf44ee9d8c53" have entirely different histories.
		
	
	
		
			3589a90385
			...
			b4eab85b19
		
	
		
					 19 changed files with 90 additions and 395 deletions
				
			
		
							
								
								
									
										2
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							|  | @ -408,7 +408,7 @@ dependencies = [ | |||
| [[package]] | ||||
| name = "servicepoint" | ||||
| version = "0.13.2" | ||||
| source = "git+https://git.berlin.ccc.de/servicepoint/servicepoint/?branch=next#114385868af03f8cba7c87a630b501bb0106d140" | ||||
| source = "git+https://git.berlin.ccc.de/servicepoint/servicepoint/?branch=next#531d4e6b4a368dc126cab9dc12b64d2ca8a81694" | ||||
| dependencies = [ | ||||
|  "bitvec", | ||||
|  "bzip2", | ||||
|  |  | |||
|  | @ -33,9 +33,6 @@ default = ["full"] | |||
| missing-docs = "warn" | ||||
| unsafe_op_in_unsafe_fn = "warn" | ||||
| 
 | ||||
| [lints.clippy] | ||||
| missing_safety_doc = "allow" | ||||
| 
 | ||||
| [package.metadata.docs.rs] | ||||
| all-features = true | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,12 +1,9 @@ | |||
| CC := gcc | ||||
| CARGO := rustup run nightly cargo | ||||
| 
 | ||||
| TARGET := x86_64-unknown-linux-musl | ||||
| PROFILE := size-optimized | ||||
| 
 | ||||
| THIS_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) | ||||
| REPO_ROOT := $(THIS_DIR)/.. | ||||
| RUST_TARGET_DIR := $(REPO_ROOT)/target/$(TARGET)/$(PROFILE) | ||||
| RUST_TARGET_DIR := $(REPO_ROOT)/target/x86_64-unknown-linux-musl/size-optimized | ||||
| export SERVICEPOINT_HEADER_OUT := $(REPO_ROOT)/include | ||||
| 
 | ||||
| RUSTFLAGS := -Zlocation-detail=none \
 | ||||
|  | @ -20,9 +17,9 @@ RUSTFLAGS := -Zlocation-detail=none \ | |||
| 	-C panic=abort | ||||
| 
 | ||||
| CARGOFLAGS := --manifest-path=$(REPO_ROOT)/Cargo.toml \
 | ||||
| 	--profile=$(PROFILE) \
 | ||||
| 	--profile=size-optimized \
 | ||||
| 	--no-default-features \
 | ||||
| 	--target=$(TARGET) \
 | ||||
| 	--target=x86_64-unknown-linux-musl \
 | ||||
| 	-Zbuild-std="core,std,alloc,proc_macro,panic_abort" \
 | ||||
| 	-Zbuild-std-features="panic_immediate_abort" \
 | ||||
| 
 | ||||
|  | @ -40,31 +37,28 @@ CCFLAGS := -static -Os \ | |||
| 	-fvisibility=hidden \
 | ||||
| 	-Bsymbolic \
 | ||||
| 	-Wl,--exclude-libs,ALL \
 | ||||
| 	-fno-ident \
 | ||||
| 	-Wall | ||||
| 	-fno-ident | ||||
| 	#-fuse-ld=gold \ | ||||
| 	-fno-exceptions | ||||
| 	#-Wl,--icf=all \ | ||||
| 
 | ||||
| STRIPFLAGS := -s --strip-unneeded -R .comment -R .gnu.version -R .comment -R .note -R .note.gnu.build-id -R .note.ABI-tag | ||||
| 
 | ||||
| _c_src := $(wildcard *.c) | ||||
| _programs := $(basename $(_c_src)) | ||||
| _bins := $(addprefix out/, $(_programs)) | ||||
| _unstripped_bins := $(addsuffix _unstripped, $(_bins)) | ||||
| _run_programs := $(addprefix run_, $(_programs)) | ||||
| _rs_src := $(wildcard ../src/**.rs) ../Cargo.lock | ||||
| src := $(wildcard *.c) | ||||
| programs := $(basename $(src)) | ||||
| bins := $(addprefix out/, $(programs)) | ||||
| unstripped_bins := $(addsuffix _unstripped, $(bins)) | ||||
| 
 | ||||
| all: $(_bins) | ||||
| all: $(bins) | ||||
| 
 | ||||
| clean: | ||||
| 	rm -r out || true | ||||
| 	rm include/servicepoint.h || true | ||||
| 	cargo clean | ||||
| 
 | ||||
| PHONY: all clean sizes $(_run_programs) | ||||
| PHONY: all clean analyze-size | ||||
| 
 | ||||
| $(_unstripped_bins): out/%_unstripped: %.c $(SERVICEPOINT_HEADER_OUT)/servicepoint.h $(RUST_TARGET_DIR)/libservicepoint_binding_c.a | ||||
| $(unstripped_bins): out/%_unstripped: %.c $(SERVICEPOINT_HEADER_OUT)/servicepoint.h | ||||
| 	mkdir -p out || true | ||||
| 	${CC} $^ \
 | ||||
| 		-I $(SERVICEPOINT_HEADER_OUT) \
 | ||||
|  | @ -72,23 +66,17 @@ $(_unstripped_bins): out/%_unstripped: %.c $(SERVICEPOINT_HEADER_OUT)/servicepoi | |||
| 		$(CCFLAGS) \
 | ||||
| 		-o $@ | ||||
| 
 | ||||
| $(_bins): out/%: out/%_unstripped | ||||
| $(bins): out/%: out/%_unstripped | ||||
| 	strip $(STRIPFLAGS) $^ -o $@ | ||||
| 
 | ||||
| $(SERVICEPOINT_HEADER_OUT)/servicepoint.h $(RUST_TARGET_DIR)/libservicepoint_binding_c.a: $(_rs_src) | ||||
| $(SERVICEPOINT_HEADER_OUT)/servicepoint.h: FORCE | ||||
| 	mkdir -p include || true | ||||
| 	# generate servicepoint header and binary to link against | ||||
| 	${CARGO} rustc $(CARGOFLAGS) -- $(RUSTFLAGS) | ||||
| 
 | ||||
| $(_run_programs): run_%: out/% FORCE | ||||
| 	./$< | ||||
| 
 | ||||
| sizes: $(_bins) | ||||
| 	ls -lB out | ||||
| 
 | ||||
| #analyze-size: out/example_unstripped
 | ||||
| #	nm --print-size --size-sort --reverse-sort --radix=d --demangle out/example_unstripped \
 | ||||
| #		| awk '{size=$$2+0; print size "\t" $$4}' \
 | ||||
| #		| less
 | ||||
| analyze-size: out/example_unstripped | ||||
| 	nm --print-size --size-sort --reverse-sort --radix=d --demangle out/example_unstripped \
 | ||||
| 		| awk '{size=$$2+0; print size "\t" $$4}' \
 | ||||
| 		| less | ||||
| 
 | ||||
| FORCE: ; | ||||
|  |  | |||
|  | @ -1,17 +1,17 @@ | |||
| #include <stdio.h> | ||||
| #include "servicepoint.h" | ||||
| 
 | ||||
| int main(void) { | ||||
|     //UdpConnection *connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342);
 | ||||
|     UdpConnection *connection = sp_udp_open_ipv4(127, 0, 0, 1, 2342); | ||||
|     UdpConnection *connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342); | ||||
|     if (connection == NULL) | ||||
|         return 1; | ||||
| 
 | ||||
|     sp_udp_send_header(connection, (Header) {.command_code = COMMAND_CODE_CLEAR}); | ||||
|     sp_udp_send_command(connection, sp_command_clear()); | ||||
| 
 | ||||
|     CharGrid *grid = sp_char_grid_new(5, 2); | ||||
|     CharGrid *grid = sp_char_grid_new(5,2); | ||||
|     if (grid == NULL) | ||||
|         return 1; | ||||
|      | ||||
| 
 | ||||
|     sp_char_grid_set(grid, 0, 0, 'H'); | ||||
|     sp_char_grid_set(grid, 1, 0, 'e'); | ||||
|     sp_char_grid_set(grid, 2, 0, 'l'); | ||||
|  | @ -23,10 +23,9 @@ int main(void) { | |||
|     sp_char_grid_set(grid, 3, 1, 'l'); | ||||
|     sp_char_grid_set(grid, 4, 1, 'd'); | ||||
| 
 | ||||
|     Packet *packet = sp_char_grid_into_packet(grid, 0, 0); | ||||
|     if (packet == NULL) | ||||
|         return 1; | ||||
|     sp_udp_send_packet(connection, packet); | ||||
| 
 | ||||
|     TypedCommand *command = sp_command_char_grid(0, 0, grid); | ||||
|     sp_udp_send_command(connection, command); | ||||
| 
 | ||||
|     sp_udp_free(connection); | ||||
|     return 0; | ||||
|  |  | |||
|  | @ -1,30 +0,0 @@ | |||
| #include "servicepoint.h" | ||||
| 
 | ||||
| int main(void) { | ||||
|     // UdpConnection *connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342);
 | ||||
|     UdpConnection *connection = sp_udp_open_ipv4(127, 0, 0, 1, 2342); | ||||
|     if (connection == NULL) | ||||
|         return -1; | ||||
| 
 | ||||
|     Bitmap *all_on = sp_bitmap_new_max_sized(); | ||||
|     sp_bitmap_fill(all_on, true); | ||||
| 
 | ||||
|     Packet *packet = sp_bitmap_into_packet(all_on, 0, 0, COMPRESSION_CODE_UNCOMPRESSED); | ||||
|     if (packet == NULL) | ||||
|         return -1; | ||||
| 
 | ||||
|     sp_udp_send_packet(connection, packet); | ||||
| 
 | ||||
|     BrightnessGrid *grid = sp_brightness_grid_new(TILE_WIDTH, TILE_HEIGHT); | ||||
| 
 | ||||
|     ByteSlice slice = sp_brightness_grid_unsafe_data_ref(grid); | ||||
|     for (size_t index = 0; index < slice.length; index++) { | ||||
|         slice.start[index] = (uint8_t) (index % ((size_t) Brightness_MAX)); | ||||
|     } | ||||
| 
 | ||||
|     packet = sp_brightness_grid_into_packet(grid, 0, 0); | ||||
|     sp_udp_send_packet(connection, packet); | ||||
| 
 | ||||
|     sp_udp_free(connection); | ||||
|     return 0; | ||||
| } | ||||
|  | @ -8,16 +8,18 @@ int main(void) { | |||
| 
 | ||||
|     Bitmap *pixels = sp_bitmap_new(PIXEL_WIDTH, PIXEL_HEIGHT); | ||||
|     if (pixels == NULL) | ||||
|         return 1; | ||||
|       return 1; | ||||
| 
 | ||||
|     sp_bitmap_fill(pixels, true); | ||||
| 
 | ||||
|     Packet *packet = sp_bitmap_into_packet(pixels, 0, 0, COMPRESSION_CODE_UNCOMPRESSED); | ||||
|     if (packet == NULL) | ||||
|         return 1; | ||||
|     TypedCommand *command = sp_command_bitmap(0, 0, pixels, COMPRESSION_CODE_UNCOMPRESSED); | ||||
|     if (command == NULL) | ||||
|       return 1; | ||||
| 
 | ||||
|     Packet *packet = sp_packet_from_command(command); | ||||
| 
 | ||||
|     Header *header = sp_packet_get_header(packet); | ||||
|     printf("[%d, %d, %d, %d, %d]\n", header->command_code, header->a, header->b, header->c, header->d); | ||||
|     //printf("[%d, %d, %d, %d, %d]\n", header->command_code, header->a, header->b, header->c, header->d);
 | ||||
| 
 | ||||
|     sp_udp_send_packet(connection, packet); | ||||
| 
 | ||||
|  |  | |||
|  | @ -59,6 +59,7 @@ | |||
|               gcc | ||||
|               gnumake | ||||
|               pkg-config | ||||
| 
 | ||||
|             ]; | ||||
| 
 | ||||
|             RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}"; | ||||
|  |  | |||
|  | @ -95,36 +95,6 @@ enum BinaryOperation | |||
| typedef uint8_t BinaryOperation; | ||||
| #endif // __cplusplus
 | ||||
| 
 | ||||
| /**
 | ||||
|  * The u16 command codes used for the [Command]s. | ||||
|  */ | ||||
| enum CommandCode | ||||
| #ifdef __cplusplus | ||||
|   : uint16_t | ||||
| #endif // __cplusplus
 | ||||
|  { | ||||
|     COMMAND_CODE_CLEAR = 2, | ||||
|     COMMAND_CODE_CP437_DATA = 3, | ||||
|     COMMAND_CODE_CHAR_BRIGHTNESS = 5, | ||||
|     COMMAND_CODE_BRIGHTNESS = 7, | ||||
|     COMMAND_CODE_HARD_RESET = 11, | ||||
|     COMMAND_CODE_FADE_OUT = 13, | ||||
|     COMMAND_CODE_BITMAP_LEGACY = 16, | ||||
|     COMMAND_CODE_BITMAP_LINEAR = 18, | ||||
|     COMMAND_CODE_BITMAP_LINEAR_WIN_UNCOMPRESSED = 19, | ||||
|     COMMAND_CODE_BITMAP_LINEAR_AND = 20, | ||||
|     COMMAND_CODE_BITMAP_LINEAR_OR = 21, | ||||
|     COMMAND_CODE_BITMAP_LINEAR_XOR = 22, | ||||
|     COMMAND_CODE_BITMAP_LINEAR_WIN_ZLIB = 23, | ||||
|     COMMAND_CODE_BITMAP_LINEAR_WIN_BZIP2 = 24, | ||||
|     COMMAND_CODE_BITMAP_LINEAR_WIN_LZMA = 25, | ||||
|     COMMAND_CODE_UTF8_DATA = 32, | ||||
|     COMMAND_CODE_BITMAP_LINEAR_WIN_ZSTD = 26, | ||||
| }; | ||||
| #ifndef __cplusplus | ||||
| typedef uint16_t CommandCode; | ||||
| #endif // __cplusplus
 | ||||
| 
 | ||||
| /**
 | ||||
|  * Specifies the kind of compression to use. Availability depends on features. | ||||
|  * | ||||
|  | @ -455,18 +425,6 @@ size_t sp_bitmap_height(Bitmap */*notnull*/ bitmap); | |||
|  */ | ||||
| SPBitVec */*notnull*/ sp_bitmap_into_bitvec(Bitmap */*notnull*/ bitmap); | ||||
| 
 | ||||
| /**
 | ||||
|  * Creates a [BitmapCommand] and immediately turns that into a [Packet]. | ||||
|  * | ||||
|  * The provided [Bitmap] gets consumed. | ||||
|  * | ||||
|  * Returns NULL in case of an error. | ||||
|  */ | ||||
| Packet *sp_bitmap_into_packet(Bitmap */*notnull*/ bitmap, | ||||
|                               size_t x, | ||||
|                               size_t y, | ||||
|                               CompressionCode compression); | ||||
| 
 | ||||
| /**
 | ||||
|  * Loads a [Bitmap] with the specified dimensions from the provided data. | ||||
|  * | ||||
|  | @ -592,18 +550,6 @@ void sp_bitvec_free(SPBitVec */*notnull*/ bit_vec); | |||
|  */ | ||||
| bool sp_bitvec_get(SPBitVec */*notnull*/ bit_vec, size_t index); | ||||
| 
 | ||||
| /**
 | ||||
|  * Creates a [BitVecCommand] and immediately turns that into a [Packet]. | ||||
|  * | ||||
|  * The provided [SPBitVec] gets consumed. | ||||
|  * | ||||
|  * Returns NULL in case of an error. | ||||
|  */ | ||||
| Packet *sp_bitvec_into_packet(SPBitVec */*notnull*/ bitvec, | ||||
|                               size_t offset, | ||||
|                               BinaryOperation operation, | ||||
|                               CompressionCode compression); | ||||
| 
 | ||||
| /**
 | ||||
|  * Returns true if length is 0. | ||||
|  * | ||||
|  | @ -719,17 +665,6 @@ Brightness sp_brightness_grid_get(BrightnessGrid */*notnull*/ brightness_grid, | |||
|  */ | ||||
| size_t sp_brightness_grid_height(BrightnessGrid */*notnull*/ brightness_grid); | ||||
| 
 | ||||
| /**
 | ||||
|  * Creates a [BrightnessGridCommand] and immediately turns that into a [Packet]. | ||||
|  * | ||||
|  * The provided [BrightnessGrid] gets consumed. | ||||
|  * | ||||
|  * Returns NULL in case of an error. | ||||
|  */ | ||||
| Packet *sp_brightness_grid_into_packet(BrightnessGrid */*notnull*/ grid, | ||||
|                                        size_t x, | ||||
|                                        size_t y); | ||||
| 
 | ||||
| /**
 | ||||
|  * Loads a [BrightnessGrid] with the specified dimensions from the provided data. | ||||
|  * | ||||
|  | @ -748,7 +683,7 @@ BrightnessGrid *sp_brightness_grid_load(size_t width, | |||
|  * | ||||
|  * # Examples | ||||
|  * ```C | ||||
|  * UdpConnection connection = sp_udp_open("127.0.0.1:2342"); | ||||
|  * UdpConnection connection = sp_connection_open("127.0.0.1:2342"); | ||||
|  * if (connection == NULL) | ||||
|  *     return 1; | ||||
|  * | ||||
|  | @ -757,7 +692,7 @@ BrightnessGrid *sp_brightness_grid_load(size_t width, | |||
|  * sp_brightness_grid_set(grid, 1, 1, 10); | ||||
|  * | ||||
|  * TypedCommand command = sp_command_char_brightness(grid); | ||||
|  * sp_udp_free(connection); | ||||
|  * sp_connection_free(connection); | ||||
|  * ``` | ||||
|  */ | ||||
| BrightnessGrid */*notnull*/ sp_brightness_grid_new(size_t width, size_t height); | ||||
|  | @ -849,17 +784,6 @@ uint32_t sp_char_grid_get(CharGrid */*notnull*/ char_grid, size_t x, size_t y); | |||
|  */ | ||||
| size_t sp_char_grid_height(CharGrid */*notnull*/ char_grid); | ||||
| 
 | ||||
| /**
 | ||||
|  * Creates a [CharGridCommand] and immediately turns that into a [Packet]. | ||||
|  * | ||||
|  * The provided [CharGrid] gets consumed. | ||||
|  * | ||||
|  * Returns NULL in case of an error. | ||||
|  */ | ||||
| Packet *sp_char_grid_into_packet(CharGrid */*notnull*/ grid, | ||||
|                                  size_t x, | ||||
|                                  size_t y); | ||||
| 
 | ||||
| /**
 | ||||
|  * Loads a [CharGrid] with the specified dimensions from the provided data. | ||||
|  * | ||||
|  | @ -975,7 +899,7 @@ TypedCommand */*notnull*/ sp_command_char_grid(size_t x, | |||
|  * # Examples | ||||
|  * | ||||
|  * ```C | ||||
|  * sp_udp_send_command(connection, sp_command_clear()); | ||||
|  * sp_connection_send_command(connection, sp_command_clear()); | ||||
|  * ``` | ||||
|  */ | ||||
| TypedCommand */*notnull*/ sp_command_clear(void); | ||||
|  | @ -1087,17 +1011,6 @@ uint8_t sp_cp437_grid_get(Cp437Grid */*notnull*/ cp437_grid, | |||
|  */ | ||||
| size_t sp_cp437_grid_height(Cp437Grid */*notnull*/ cp437_grid); | ||||
| 
 | ||||
| /**
 | ||||
|  * Creates a [Cp437GridCommand] and immediately turns that into a [Packet]. | ||||
|  * | ||||
|  * The provided [Cp437Grid] gets consumed. | ||||
|  * | ||||
|  * Returns NULL in case of an error. | ||||
|  */ | ||||
| Packet *sp_cp437_grid_into_packet(Cp437Grid */*notnull*/ grid, | ||||
|                                   size_t x, | ||||
|                                   size_t y); | ||||
| 
 | ||||
| /**
 | ||||
|  * Loads a [Cp437Grid] with the specified dimensions from the provided data. | ||||
|  */ | ||||
|  | @ -1209,14 +1122,6 @@ void sp_packet_set_payload(Packet */*notnull*/ packet, ByteSlice data); | |||
|  */ | ||||
| Packet *sp_packet_try_load(ByteSlice data); | ||||
| 
 | ||||
| /**
 | ||||
|  * Converts u16 into [CommandCode]. | ||||
|  * | ||||
|  * If the provided value is not valid, false is returned and result is not changed. | ||||
|  */ | ||||
| bool sp_u16_to_command_code(uint16_t code, | ||||
|                             CommandCode *result); | ||||
| 
 | ||||
| /**
 | ||||
|  * Closes and deallocates a [UdpConnection]. | ||||
|  */ | ||||
|  | @ -1230,9 +1135,9 @@ void sp_udp_free(UdpConnection */*notnull*/ connection); | |||
|  * # Examples | ||||
|  * | ||||
|  * ```C | ||||
|  * UdpConnection connection = sp_udp_open("172.23.42.29:2342"); | ||||
|  * UdpConnection connection = sp_connection_open("172.23.42.29:2342"); | ||||
|  * if (connection != NULL) | ||||
|  *     sp_udp_send_command(connection, sp_command_clear()); | ||||
|  *     sp_connection_send_command(connection, sp_command_clear()); | ||||
|  * ``` | ||||
|  */ | ||||
| UdpConnection *sp_udp_open(char */*notnull*/ host); | ||||
|  | @ -1245,9 +1150,9 @@ UdpConnection *sp_udp_open(char */*notnull*/ host); | |||
|  * # Examples | ||||
|  * | ||||
|  * ```C | ||||
|  * UdpConnection connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342); | ||||
|  * UdpConnection connection = sp_connection_open_ipv4(172, 23, 42, 29, 2342); | ||||
|  * if (connection != NULL) | ||||
|  *     sp_udp_send_command(connection, sp_command_clear()); | ||||
|  *     sp_connection_send_command(connection, sp_command_clear()); | ||||
|  * ``` | ||||
|  */ | ||||
| UdpConnection *sp_udp_open_ipv4(uint8_t ip1, | ||||
|  | @ -1266,26 +1171,13 @@ UdpConnection *sp_udp_open_ipv4(uint8_t ip1, | |||
|  * # Examples | ||||
|  * | ||||
|  * ```C | ||||
|  * sp_udp_send_command(connection, sp_command_brightness(5)); | ||||
|  * sp_connection_send_command(connection, sp_command_clear()); | ||||
|  * sp_connection_send_command(connection, sp_command_brightness(5)); | ||||
|  * ``` | ||||
|  */ | ||||
| bool sp_udp_send_command(UdpConnection */*notnull*/ connection, | ||||
|                          TypedCommand */*notnull*/ command); | ||||
| 
 | ||||
| /**
 | ||||
|  * Sends a [Header] to the display using the [UdpConnection]. | ||||
|  * | ||||
|  * returns: true in case of success | ||||
|  * | ||||
|  * # Examples | ||||
|  * | ||||
|  * ```C | ||||
|  * sp_udp_send_header(connection, sp_command_brightness(5)); | ||||
|  * ``` | ||||
|  */ | ||||
| bool sp_udp_send_header(UdpConnection */*notnull*/ udp_connection, | ||||
|                         Header header); | ||||
| 
 | ||||
| /**
 | ||||
|  * Sends a [Packet] to the display using the [UdpConnection]. | ||||
|  * | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| use crate::byte_slice::ByteSlice; | ||||
| use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, SPBitVec}; | ||||
| use servicepoint::{Bitmap, BitmapCommand, CompressionCode, DataRef, Grid, Origin, Packet}; | ||||
| use crate::{heap_drop, heap_move, heap_move_nonnull, SPBitVec}; | ||||
| use servicepoint::{Bitmap, DataRef, Grid}; | ||||
| use std::ptr::NonNull; | ||||
| 
 | ||||
| /// Creates a new [Bitmap] with the specified dimensions.
 | ||||
|  | @ -78,7 +78,7 @@ pub unsafe extern "C" fn sp_bitmap_from_bitvec( | |||
|     width: usize, | ||||
|     bitvec: NonNull<SPBitVec>, | ||||
| ) -> *mut Bitmap { | ||||
|     let bitvec = unsafe { heap_remove(bitvec) }; | ||||
|     let bitvec = unsafe { *Box::from_raw(bitvec.as_ptr()) }; | ||||
|     if let Ok(bitmap) = Bitmap::from_bitvec(width, bitvec.0) { | ||||
|         heap_move(bitmap) | ||||
|     } else { | ||||
|  | @ -196,29 +196,6 @@ pub unsafe extern "C" fn sp_bitmap_unsafe_data_ref( | |||
| pub unsafe extern "C" fn sp_bitmap_into_bitvec( | ||||
|     bitmap: NonNull<Bitmap>, | ||||
| ) -> NonNull<SPBitVec> { | ||||
|     let bitmap = unsafe { heap_remove(bitmap) }; | ||||
|     let bitmap = unsafe { *Box::from_raw(bitmap.as_ptr()) }; | ||||
|     heap_move_nonnull(SPBitVec(bitmap.into())) | ||||
| } | ||||
| 
 | ||||
| /// Creates a [BitmapCommand] and immediately turns that into a [Packet].
 | ||||
| ///
 | ||||
| /// The provided [Bitmap] gets consumed.
 | ||||
| ///
 | ||||
| /// Returns NULL in case of an error.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bitmap_into_packet( | ||||
|     bitmap: NonNull<Bitmap>, | ||||
|     x: usize, | ||||
|     y: usize, | ||||
|     compression: CompressionCode | ||||
| ) -> *mut Packet { | ||||
|     let bitmap = unsafe { heap_remove(bitmap) }; | ||||
|     match Packet::try_from(BitmapCommand { | ||||
|         bitmap, | ||||
|         origin: Origin::new(x, y), | ||||
|         compression, | ||||
|     }) { | ||||
|         Ok(packet) => heap_move(packet), | ||||
|         Err(_) => std::ptr::null_mut(), | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice}; | ||||
| use servicepoint::{BinaryOperation, BitVecCommand, BitVecU8Msb0, CompressionCode, Packet}; | ||||
| use crate::{heap_drop, heap_move_nonnull, ByteSlice}; | ||||
| use servicepoint::BitVecU8Msb0; | ||||
| use std::ptr::NonNull; | ||||
| 
 | ||||
| /// A vector of bits
 | ||||
|  | @ -146,27 +146,3 @@ pub unsafe extern "C" fn sp_bitvec_unsafe_data_ref( | |||
| ) -> ByteSlice { | ||||
|     unsafe { ByteSlice::from_slice((*bit_vec.as_ptr()).0.as_raw_mut_slice()) } | ||||
| } | ||||
| 
 | ||||
| /// Creates a [BitVecCommand] and immediately turns that into a [Packet].
 | ||||
| ///
 | ||||
| /// The provided [SPBitVec] gets consumed.
 | ||||
| ///
 | ||||
| /// Returns NULL in case of an error.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bitvec_into_packet( | ||||
|     bitvec: NonNull<SPBitVec>, | ||||
|     offset: usize, | ||||
|     operation: BinaryOperation, | ||||
|     compression: CompressionCode | ||||
| ) -> *mut Packet { | ||||
|     let bitvec = unsafe { heap_remove(bitvec) }.0; | ||||
|     match Packet::try_from(BitVecCommand { | ||||
|         bitvec, | ||||
|         offset, | ||||
|         operation, | ||||
|         compression, | ||||
|     }) { | ||||
|         Ok(packet) => heap_move(packet), | ||||
|         Err(_) => std::ptr::null_mut(), | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,8 +1,5 @@ | |||
| use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice}; | ||||
| use servicepoint::{ | ||||
|     Brightness, BrightnessGrid, BrightnessGridCommand, ByteGrid, DataRef, Grid, | ||||
|     Origin, Packet, | ||||
| }; | ||||
| use crate::{heap_drop, heap_move, heap_move_nonnull, ByteSlice}; | ||||
| use servicepoint::{Brightness, BrightnessGrid, ByteGrid, DataRef, Grid}; | ||||
| use std::mem::transmute; | ||||
| use std::ptr::NonNull; | ||||
| 
 | ||||
|  | @ -12,7 +9,7 @@ use std::ptr::NonNull; | |||
| ///
 | ||||
| /// # Examples
 | ||||
| /// ```C
 | ||||
| /// UdpConnection connection = sp_udp_open("127.0.0.1:2342");
 | ||||
| /// UdpConnection connection = sp_connection_open("127.0.0.1:2342");
 | ||||
| /// if (connection == NULL)
 | ||||
| ///     return 1;
 | ||||
| ///
 | ||||
|  | @ -21,7 +18,7 @@ use std::ptr::NonNull; | |||
| /// sp_brightness_grid_set(grid, 1, 1, 10);
 | ||||
| ///
 | ||||
| /// TypedCommand command = sp_command_char_brightness(grid);
 | ||||
| /// sp_udp_free(connection);
 | ||||
| /// sp_connection_free(connection);
 | ||||
| /// ```
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_brightness_grid_new( | ||||
|  | @ -170,28 +167,5 @@ pub unsafe extern "C" fn sp_brightness_grid_unsafe_data_ref( | |||
|     const _: () = assert!(size_of::<Brightness>() == 1); | ||||
| 
 | ||||
|     let data = unsafe { (*brightness_grid.as_ptr()).data_ref_mut() }; | ||||
|     unsafe { | ||||
|         ByteSlice::from_slice(transmute::<&mut [Brightness], &mut [u8]>(data)) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Creates a [BrightnessGridCommand] and immediately turns that into a [Packet].
 | ||||
| ///
 | ||||
| /// The provided [BrightnessGrid] gets consumed.
 | ||||
| ///
 | ||||
| /// Returns NULL in case of an error.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_brightness_grid_into_packet( | ||||
|     grid: NonNull<BrightnessGrid>, | ||||
|     x: usize, | ||||
|     y: usize, | ||||
| ) -> *mut Packet { | ||||
|     let grid = unsafe { heap_remove(grid) }; | ||||
|     match Packet::try_from(BrightnessGridCommand { | ||||
|         grid, | ||||
|         origin: Origin::new(x, y), | ||||
|     }) { | ||||
|         Ok(packet) => heap_move(packet), | ||||
|         Err(_) => std::ptr::null_mut(), | ||||
|     } | ||||
|     unsafe { ByteSlice::from_slice(transmute(data)) } | ||||
| } | ||||
|  |  | |||
|  | @ -24,7 +24,7 @@ impl ByteSlice { | |||
|         unsafe { std::slice::from_raw_parts(self.start.as_ptr(), self.length) } | ||||
|     } | ||||
| 
 | ||||
|     pub(crate) unsafe fn as_slice_mut(&mut self) -> &mut [u8] { | ||||
|     pub(crate) unsafe fn as_slice_mut(&self) -> &mut [u8] { | ||||
|         unsafe { | ||||
|             std::slice::from_raw_parts_mut(self.start.as_ptr(), self.length) | ||||
|         } | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice}; | ||||
| use servicepoint::{CharGrid, CharGridCommand, Grid, Origin, Packet}; | ||||
| use crate::{heap_drop, heap_move, heap_move_nonnull, ByteSlice}; | ||||
| use servicepoint::{CharGrid, Grid}; | ||||
| use std::ptr::NonNull; | ||||
| 
 | ||||
| /// Creates a new [CharGrid] with the specified dimensions.
 | ||||
|  | @ -132,24 +132,3 @@ pub unsafe extern "C" fn sp_char_grid_height( | |||
| ) -> usize { | ||||
|     unsafe { char_grid.as_ref().height() } | ||||
| } | ||||
| 
 | ||||
| /// Creates a [CharGridCommand] and immediately turns that into a [Packet].
 | ||||
| ///
 | ||||
| /// The provided [CharGrid] gets consumed.
 | ||||
| ///
 | ||||
| /// Returns NULL in case of an error.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_char_grid_into_packet( | ||||
|     grid: NonNull<CharGrid>, | ||||
|     x: usize, | ||||
|     y: usize, | ||||
| ) -> *mut Packet { | ||||
|     let grid = unsafe { heap_remove(grid) }; | ||||
|     match Packet::try_from(CharGridCommand { | ||||
|         grid, | ||||
|         origin: Origin::new(x, y), | ||||
|     }) { | ||||
|         Ok(packet) => heap_move(packet), | ||||
|         Err(_) => std::ptr::null_mut(), | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -40,7 +40,7 @@ pub unsafe extern "C" fn sp_command_clone( | |||
| /// # Examples
 | ||||
| ///
 | ||||
| /// ```C
 | ||||
| /// sp_udp_send_command(connection, sp_command_clear());
 | ||||
| /// sp_connection_send_command(connection, sp_command_clear());
 | ||||
| /// ```
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_clear() -> NonNull<TypedCommand> { | ||||
|  | @ -115,6 +115,10 @@ pub unsafe extern "C" fn sp_command_bitvec( | |||
|     operation: BinaryOperation, | ||||
| ) -> *mut TypedCommand { | ||||
|     let bit_vec = unsafe { *Box::from_raw(bit_vec.as_ptr()) }; | ||||
|     let compression = match compression.try_into() { | ||||
|         Ok(compression) => compression, | ||||
|         Err(_) => return std::ptr::null_mut(), | ||||
|     }; | ||||
|     let command = servicepoint::BitVecCommand { | ||||
|         offset, | ||||
|         operation, | ||||
|  | @ -178,6 +182,10 @@ pub unsafe extern "C" fn sp_command_bitmap( | |||
|     compression: CompressionCode, | ||||
| ) -> *mut TypedCommand { | ||||
|     let bitmap = unsafe { *Box::from_raw(bitmap.as_ptr()) }; | ||||
|     let compression = match compression.try_into() { | ||||
|         Ok(compression) => compression, | ||||
|         Err(_) => return std::ptr::null_mut(), | ||||
|     }; | ||||
|     let command = servicepoint::BitmapCommand { | ||||
|         origin: servicepoint::Origin::new(x, y), | ||||
|         bitmap, | ||||
|  | @ -1,3 +0,0 @@ | |||
| mod typed; | ||||
| 
 | ||||
| pub use typed::*; | ||||
|  | @ -1,5 +1,5 @@ | |||
| use crate::{heap_drop, heap_move, heap_remove}; | ||||
| use servicepoint::{Connection, Header, Packet, TypedCommand, UdpConnection}; | ||||
| use crate::{heap_drop, heap_move}; | ||||
| use servicepoint::{Connection, Packet, TypedCommand, UdpConnection}; | ||||
| use std::ffi::{c_char, CStr}; | ||||
| use std::net::{Ipv4Addr, SocketAddrV4}; | ||||
| use std::ptr::NonNull; | ||||
|  | @ -11,9 +11,9 @@ use std::ptr::NonNull; | |||
| /// # Examples
 | ||||
| ///
 | ||||
| /// ```C
 | ||||
| /// UdpConnection connection = sp_udp_open("172.23.42.29:2342");
 | ||||
| /// UdpConnection connection = sp_connection_open("172.23.42.29:2342");
 | ||||
| /// if (connection != NULL)
 | ||||
| ///     sp_udp_send_command(connection, sp_command_clear());
 | ||||
| ///     sp_connection_send_command(connection, sp_command_clear());
 | ||||
| /// ```
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_udp_open( | ||||
|  | @ -37,9 +37,9 @@ pub unsafe extern "C" fn sp_udp_open( | |||
| /// # Examples
 | ||||
| ///
 | ||||
| /// ```C
 | ||||
| /// UdpConnection connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342);
 | ||||
| /// UdpConnection connection = sp_connection_open_ipv4(172, 23, 42, 29, 2342);
 | ||||
| /// if (connection != NULL)
 | ||||
| ///     sp_udp_send_command(connection, sp_command_clear());
 | ||||
| ///     sp_connection_send_command(connection, sp_command_clear());
 | ||||
| /// ```
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_udp_open_ipv4( | ||||
|  | @ -67,8 +67,8 @@ pub unsafe extern "C" fn sp_udp_send_packet( | |||
|     connection: NonNull<UdpConnection>, | ||||
|     packet: NonNull<Packet>, | ||||
| ) -> bool { | ||||
|     let packet = unsafe { heap_remove(packet) }; | ||||
|     unsafe { connection.as_ref().send(packet) }.is_ok() | ||||
|     let packet = unsafe { Box::from_raw(packet.as_ptr()) }; | ||||
|     unsafe { connection.as_ref().send(*packet) }.is_ok() | ||||
| } | ||||
| 
 | ||||
| /// Sends a [TypedCommand] to the display using the [UdpConnection].
 | ||||
|  | @ -80,38 +80,18 @@ pub unsafe extern "C" fn sp_udp_send_packet( | |||
| /// # Examples
 | ||||
| ///
 | ||||
| /// ```C
 | ||||
| /// sp_udp_send_command(connection, sp_command_brightness(5));
 | ||||
| /// 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_udp_send_command( | ||||
|     connection: NonNull<UdpConnection>, | ||||
|     command: NonNull<TypedCommand>, | ||||
| ) -> bool { | ||||
|     let command = unsafe { heap_remove(command) }; | ||||
|     let command = *unsafe { Box::from_raw(command.as_ptr()) }; | ||||
|     unsafe { connection.as_ref().send(command) }.is_ok() | ||||
| } | ||||
| 
 | ||||
| /// Sends a [Header] to the display using the [UdpConnection].
 | ||||
| ///
 | ||||
| /// returns: true in case of success
 | ||||
| ///
 | ||||
| /// # Examples
 | ||||
| ///
 | ||||
| /// ```C
 | ||||
| /// sp_udp_send_header(connection, sp_command_brightness(5));
 | ||||
| /// ```
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_udp_send_header( | ||||
|     udp_connection: NonNull<UdpConnection>, | ||||
|     header: Header, | ||||
| ) -> bool { | ||||
|     let packet = Packet { | ||||
|         header, | ||||
|         payload: vec![], | ||||
|     }; | ||||
|     unsafe { udp_connection.as_ref() }.send(packet).is_ok() | ||||
| } | ||||
| 
 | ||||
| /// Closes and deallocates a [UdpConnection].
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_udp_free(connection: NonNull<UdpConnection>) { | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice}; | ||||
| use servicepoint::{Cp437Grid, Cp437GridCommand, DataRef, Grid, Origin, Packet}; | ||||
| use crate::{heap_drop, heap_move, heap_move_nonnull, ByteSlice}; | ||||
| use servicepoint::{Cp437Grid, DataRef, Grid}; | ||||
| use std::ptr::NonNull; | ||||
| 
 | ||||
| /// Creates a new [Cp437Grid] with the specified dimensions.
 | ||||
|  | @ -132,24 +132,3 @@ pub unsafe extern "C" fn sp_cp437_grid_unsafe_data_ref( | |||
| ) -> ByteSlice { | ||||
|     unsafe { ByteSlice::from_slice((*cp437_grid.as_ptr()).data_ref_mut()) } | ||||
| } | ||||
| 
 | ||||
| /// Creates a [Cp437GridCommand] and immediately turns that into a [Packet].
 | ||||
| ///
 | ||||
| /// The provided [Cp437Grid] gets consumed.
 | ||||
| ///
 | ||||
| /// Returns NULL in case of an error.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_cp437_grid_into_packet( | ||||
|     grid: NonNull<Cp437Grid>, | ||||
|     x: usize, | ||||
|     y: usize, | ||||
| ) -> *mut Packet { | ||||
|     let grid = unsafe { heap_remove(grid) }; | ||||
|     match Packet::try_from(Cp437GridCommand { | ||||
|         grid, | ||||
|         origin: Origin::new(x, y), | ||||
|     }) { | ||||
|         Ok(packet) => heap_move(packet), | ||||
|         Err(_) => std::ptr::null_mut(), | ||||
|     } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										17
									
								
								src/lib.rs
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								src/lib.rs
									
										
									
									
									
								
							|  | @ -9,7 +9,7 @@ | |||
| //! #include "servicepoint.h"
 | ||||
| //!
 | ||||
| //! int main(void) {
 | ||||
| //!     UdpConnection *connection = sp_udp_open("172.23.42.29:2342");
 | ||||
| //!     UdpConnection *connection = sp_connection_open("172.23.42.29:2342");
 | ||||
| //!     if (connection == NULL)
 | ||||
| //!         return 1;
 | ||||
| //!
 | ||||
|  | @ -17,10 +17,10 @@ | |||
| //!     sp_bitmap_fill(pixels, true);
 | ||||
| //!
 | ||||
| //!     TypedCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, Uncompressed);
 | ||||
| //!     while (sp_udp_send_command(connection, sp_command_clone(command)));
 | ||||
| //!     while (sp_connection_send_command(connection, sp_command_clone(command)));
 | ||||
| //!
 | ||||
| //!     sp_command_free(command);
 | ||||
| //!     sp_udp_free(connection);
 | ||||
| //!     sp_connection_free(connection);
 | ||||
| //!     return 0;
 | ||||
| //! }
 | ||||
| //! ```
 | ||||
|  | @ -30,11 +30,10 @@ pub use crate::bitvec::*; | |||
| pub use crate::brightness_grid::*; | ||||
| pub use crate::byte_slice::*; | ||||
| pub use crate::char_grid::*; | ||||
| pub use crate::commands::*; | ||||
| pub use crate::command::*; | ||||
| pub use crate::connection::*; | ||||
| pub use crate::cp437_grid::*; | ||||
| pub use crate::packet::*; | ||||
| pub use servicepoint::CommandCode; | ||||
| use std::ptr::NonNull; | ||||
| 
 | ||||
| mod bitmap; | ||||
|  | @ -42,7 +41,7 @@ mod bitvec; | |||
| mod brightness_grid; | ||||
| mod byte_slice; | ||||
| mod char_grid; | ||||
| mod commands; | ||||
| mod command; | ||||
| mod connection; | ||||
| mod cp437_grid; | ||||
| mod packet; | ||||
|  | @ -61,9 +60,5 @@ pub(crate) fn heap_move_nonnull<T>(x: T) -> NonNull<T> { | |||
| } | ||||
| 
 | ||||
| pub(crate) unsafe fn heap_drop<T>(x: NonNull<T>) { | ||||
|     drop(unsafe { heap_remove(x) }); | ||||
| } | ||||
| 
 | ||||
| pub(crate) unsafe fn heap_remove<T>(x: NonNull<T>) -> T { | ||||
|     unsafe { *Box::from_raw(x.as_ptr()) } | ||||
|     drop(unsafe { Box::from_raw(x.as_ptr()) }); | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice}; | ||||
| use servicepoint::{CommandCode, Header, Packet, TypedCommand}; | ||||
| use crate::{heap_drop, heap_move, heap_move_nonnull, ByteSlice}; | ||||
| use servicepoint::{Header, Packet, TypedCommand}; | ||||
| use std::ptr::NonNull; | ||||
| 
 | ||||
| /// Turns a [TypedCommand] into a [Packet].
 | ||||
|  | @ -10,7 +10,7 @@ use std::ptr::NonNull; | |||
| pub unsafe extern "C" fn sp_packet_from_command( | ||||
|     command: NonNull<TypedCommand>, | ||||
| ) -> *mut Packet { | ||||
|     let command = unsafe { heap_remove(command) }; | ||||
|     let command = unsafe { *Box::from_raw(command.as_ptr()) }; | ||||
|     if let Ok(packet) = command.try_into() { | ||||
|         heap_move(packet) | ||||
|     } else { | ||||
|  | @ -65,7 +65,7 @@ pub unsafe extern "C" fn sp_packet_get_header( | |||
| pub unsafe extern "C" fn sp_packet_get_payload( | ||||
|     packet: NonNull<Packet>, | ||||
| ) -> ByteSlice { | ||||
|     unsafe { ByteSlice::from_slice(&mut (*packet.as_ptr()).payload) } | ||||
|     unsafe { ByteSlice::from_slice(&mut *(*packet.as_ptr()).payload) } | ||||
| } | ||||
| 
 | ||||
| /// Sets the payload of the provided packet to the provided data.
 | ||||
|  | @ -87,7 +87,7 @@ pub unsafe extern "C" fn sp_packet_set_payload( | |||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_packet_serialize_to( | ||||
|     packet: NonNull<Packet>, | ||||
|     mut buffer: ByteSlice, | ||||
|     buffer: ByteSlice, | ||||
| ) { | ||||
|     unsafe { | ||||
|         packet.as_ref().serialize_to(buffer.as_slice_mut()); | ||||
|  | @ -107,22 +107,3 @@ pub unsafe extern "C" fn sp_packet_clone( | |||
| pub unsafe extern "C" fn sp_packet_free(packet: NonNull<Packet>) { | ||||
|     unsafe { heap_drop(packet) } | ||||
| } | ||||
| 
 | ||||
| /// Converts u16 into [CommandCode].
 | ||||
| ///
 | ||||
| /// If the provided value is not valid, false is returned and result is not changed.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_u16_to_command_code( | ||||
|     code: u16, | ||||
|     result: *mut CommandCode, | ||||
| ) -> bool { | ||||
|     match CommandCode::try_from(code) { | ||||
|         Ok(code) => { | ||||
|             unsafe { | ||||
|                 *result = code; | ||||
|             } | ||||
|             true | ||||
|         } | ||||
|         Err(_) => false, | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue