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]] | [[package]] | ||||||
| name = "servicepoint" | name = "servicepoint" | ||||||
| version = "0.13.2" | 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 = [ | dependencies = [ | ||||||
|  "bitvec", |  "bitvec", | ||||||
|  "bzip2", |  "bzip2", | ||||||
|  |  | ||||||
|  | @ -33,9 +33,6 @@ default = ["full"] | ||||||
| missing-docs = "warn" | missing-docs = "warn" | ||||||
| unsafe_op_in_unsafe_fn = "warn" | unsafe_op_in_unsafe_fn = "warn" | ||||||
| 
 | 
 | ||||||
| [lints.clippy] |  | ||||||
| missing_safety_doc = "allow" |  | ||||||
| 
 |  | ||||||
| [package.metadata.docs.rs] | [package.metadata.docs.rs] | ||||||
| all-features = true | all-features = true | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,12 +1,9 @@ | ||||||
| CC := gcc | CC := gcc | ||||||
| CARGO := rustup run nightly cargo | CARGO := rustup run nightly cargo | ||||||
| 
 | 
 | ||||||
| TARGET := x86_64-unknown-linux-musl |  | ||||||
| PROFILE := size-optimized |  | ||||||
| 
 |  | ||||||
| THIS_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) | THIS_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) | ||||||
| REPO_ROOT := $(THIS_DIR)/.. | 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 | export SERVICEPOINT_HEADER_OUT := $(REPO_ROOT)/include | ||||||
| 
 | 
 | ||||||
| RUSTFLAGS := -Zlocation-detail=none \
 | RUSTFLAGS := -Zlocation-detail=none \
 | ||||||
|  | @ -20,9 +17,9 @@ RUSTFLAGS := -Zlocation-detail=none \ | ||||||
| 	-C panic=abort | 	-C panic=abort | ||||||
| 
 | 
 | ||||||
| CARGOFLAGS := --manifest-path=$(REPO_ROOT)/Cargo.toml \
 | CARGOFLAGS := --manifest-path=$(REPO_ROOT)/Cargo.toml \
 | ||||||
| 	--profile=$(PROFILE) \
 | 	--profile=size-optimized \
 | ||||||
| 	--no-default-features \
 | 	--no-default-features \
 | ||||||
| 	--target=$(TARGET) \
 | 	--target=x86_64-unknown-linux-musl \
 | ||||||
| 	-Zbuild-std="core,std,alloc,proc_macro,panic_abort" \
 | 	-Zbuild-std="core,std,alloc,proc_macro,panic_abort" \
 | ||||||
| 	-Zbuild-std-features="panic_immediate_abort" \
 | 	-Zbuild-std-features="panic_immediate_abort" \
 | ||||||
| 
 | 
 | ||||||
|  | @ -40,31 +37,28 @@ CCFLAGS := -static -Os \ | ||||||
| 	-fvisibility=hidden \
 | 	-fvisibility=hidden \
 | ||||||
| 	-Bsymbolic \
 | 	-Bsymbolic \
 | ||||||
| 	-Wl,--exclude-libs,ALL \
 | 	-Wl,--exclude-libs,ALL \
 | ||||||
| 	-fno-ident \
 | 	-fno-ident | ||||||
| 	-Wall |  | ||||||
| 	#-fuse-ld=gold \ | 	#-fuse-ld=gold \ | ||||||
| 	-fno-exceptions | 	-fno-exceptions | ||||||
| 	#-Wl,--icf=all \ | 	#-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 | 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) | src := $(wildcard *.c) | ||||||
| _programs := $(basename $(_c_src)) | programs := $(basename $(src)) | ||||||
| _bins := $(addprefix out/, $(_programs)) | bins := $(addprefix out/, $(programs)) | ||||||
| _unstripped_bins := $(addsuffix _unstripped, $(_bins)) | unstripped_bins := $(addsuffix _unstripped, $(bins)) | ||||||
| _run_programs := $(addprefix run_, $(_programs)) |  | ||||||
| _rs_src := $(wildcard ../src/**.rs) ../Cargo.lock |  | ||||||
| 
 | 
 | ||||||
| all: $(_bins) | all: $(bins) | ||||||
| 
 | 
 | ||||||
| clean: | clean: | ||||||
| 	rm -r out || true | 	rm -r out || true | ||||||
| 	rm include/servicepoint.h || true | 	rm include/servicepoint.h || true | ||||||
| 	cargo clean | 	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 | 	mkdir -p out || true | ||||||
| 	${CC} $^ \
 | 	${CC} $^ \
 | ||||||
| 		-I $(SERVICEPOINT_HEADER_OUT) \
 | 		-I $(SERVICEPOINT_HEADER_OUT) \
 | ||||||
|  | @ -72,23 +66,17 @@ $(_unstripped_bins): out/%_unstripped: %.c $(SERVICEPOINT_HEADER_OUT)/servicepoi | ||||||
| 		$(CCFLAGS) \
 | 		$(CCFLAGS) \
 | ||||||
| 		-o $@ | 		-o $@ | ||||||
| 
 | 
 | ||||||
| $(_bins): out/%: out/%_unstripped | $(bins): out/%: out/%_unstripped | ||||||
| 	strip $(STRIPFLAGS) $^ -o $@ | 	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 | 	mkdir -p include || true | ||||||
| 	# generate servicepoint header and binary to link against | 	# generate servicepoint header and binary to link against | ||||||
| 	${CARGO} rustc $(CARGOFLAGS) -- $(RUSTFLAGS) | 	${CARGO} rustc $(CARGOFLAGS) -- $(RUSTFLAGS) | ||||||
| 
 | 
 | ||||||
| $(_run_programs): run_%: out/% FORCE | 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}' \
 | ||||||
| sizes: $(_bins) | 		| less | ||||||
| 	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
 |  | ||||||
| 
 | 
 | ||||||
| FORCE: ; | FORCE: ; | ||||||
|  |  | ||||||
|  | @ -1,17 +1,17 @@ | ||||||
|  | #include <stdio.h> | ||||||
| #include "servicepoint.h" | #include "servicepoint.h" | ||||||
| 
 | 
 | ||||||
| int main(void) { | int main(void) { | ||||||
|     //UdpConnection *connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342);
 |     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) |     if (connection == NULL) | ||||||
|         return 1; |         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) |     if (grid == NULL) | ||||||
|         return 1; |         return 1; | ||||||
|      | 
 | ||||||
|     sp_char_grid_set(grid, 0, 0, 'H'); |     sp_char_grid_set(grid, 0, 0, 'H'); | ||||||
|     sp_char_grid_set(grid, 1, 0, 'e'); |     sp_char_grid_set(grid, 1, 0, 'e'); | ||||||
|     sp_char_grid_set(grid, 2, 0, 'l'); |     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, 3, 1, 'l'); | ||||||
|     sp_char_grid_set(grid, 4, 1, 'd'); |     sp_char_grid_set(grid, 4, 1, 'd'); | ||||||
| 
 | 
 | ||||||
|     Packet *packet = sp_char_grid_into_packet(grid, 0, 0); | 
 | ||||||
|     if (packet == NULL) |     TypedCommand *command = sp_command_char_grid(0, 0, grid); | ||||||
|         return 1; |     sp_udp_send_command(connection, command); | ||||||
|     sp_udp_send_packet(connection, packet); |  | ||||||
| 
 | 
 | ||||||
|     sp_udp_free(connection); |     sp_udp_free(connection); | ||||||
|     return 0; |     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); |     Bitmap *pixels = sp_bitmap_new(PIXEL_WIDTH, PIXEL_HEIGHT); | ||||||
|     if (pixels == NULL) |     if (pixels == NULL) | ||||||
|         return 1; |       return 1; | ||||||
| 
 | 
 | ||||||
|     sp_bitmap_fill(pixels, true); |     sp_bitmap_fill(pixels, true); | ||||||
| 
 | 
 | ||||||
|     Packet *packet = sp_bitmap_into_packet(pixels, 0, 0, COMPRESSION_CODE_UNCOMPRESSED); |     TypedCommand *command = sp_command_bitmap(0, 0, pixels, COMPRESSION_CODE_UNCOMPRESSED); | ||||||
|     if (packet == NULL) |     if (command == NULL) | ||||||
|         return 1; |       return 1; | ||||||
|  | 
 | ||||||
|  |     Packet *packet = sp_packet_from_command(command); | ||||||
| 
 | 
 | ||||||
|     Header *header = sp_packet_get_header(packet); |     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); |     sp_udp_send_packet(connection, packet); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -59,6 +59,7 @@ | ||||||
|               gcc |               gcc | ||||||
|               gnumake |               gnumake | ||||||
|               pkg-config |               pkg-config | ||||||
|  | 
 | ||||||
|             ]; |             ]; | ||||||
| 
 | 
 | ||||||
|             RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}"; |             RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}"; | ||||||
|  |  | ||||||
|  | @ -95,36 +95,6 @@ enum BinaryOperation | ||||||
| typedef uint8_t BinaryOperation; | typedef uint8_t BinaryOperation; | ||||||
| #endif // __cplusplus
 | #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. |  * 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); | 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. |  * 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); | 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. |  * 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); | 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. |  * Loads a [BrightnessGrid] with the specified dimensions from the provided data. | ||||||
|  * |  * | ||||||
|  | @ -748,7 +683,7 @@ BrightnessGrid *sp_brightness_grid_load(size_t width, | ||||||
|  * |  * | ||||||
|  * # Examples |  * # Examples | ||||||
|  * ```C |  * ```C | ||||||
|  * UdpConnection connection = sp_udp_open("127.0.0.1:2342"); |  * UdpConnection connection = sp_connection_open("127.0.0.1:2342"); | ||||||
|  * if (connection == NULL) |  * if (connection == NULL) | ||||||
|  *     return 1; |  *     return 1; | ||||||
|  * |  * | ||||||
|  | @ -757,7 +692,7 @@ BrightnessGrid *sp_brightness_grid_load(size_t width, | ||||||
|  * sp_brightness_grid_set(grid, 1, 1, 10); |  * sp_brightness_grid_set(grid, 1, 1, 10); | ||||||
|  * |  * | ||||||
|  * TypedCommand command = sp_command_char_brightness(grid); |  * 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); | 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); | 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. |  * 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 |  * # Examples | ||||||
|  * |  * | ||||||
|  * ```C |  * ```C | ||||||
|  * sp_udp_send_command(connection, sp_command_clear()); |  * sp_connection_send_command(connection, sp_command_clear()); | ||||||
|  * ``` |  * ``` | ||||||
|  */ |  */ | ||||||
| TypedCommand */*notnull*/ sp_command_clear(void); | 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); | 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. |  * 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); | 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]. |  * Closes and deallocates a [UdpConnection]. | ||||||
|  */ |  */ | ||||||
|  | @ -1230,9 +1135,9 @@ void sp_udp_free(UdpConnection */*notnull*/ connection); | ||||||
|  * # Examples |  * # Examples | ||||||
|  * |  * | ||||||
|  * ```C |  * ```C | ||||||
|  * UdpConnection connection = sp_udp_open("172.23.42.29:2342"); |  * UdpConnection connection = sp_connection_open("172.23.42.29:2342"); | ||||||
|  * if (connection != NULL) |  * 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); | UdpConnection *sp_udp_open(char */*notnull*/ host); | ||||||
|  | @ -1245,9 +1150,9 @@ UdpConnection *sp_udp_open(char */*notnull*/ host); | ||||||
|  * # Examples |  * # Examples | ||||||
|  * |  * | ||||||
|  * ```C |  * ```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) |  * 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, | UdpConnection *sp_udp_open_ipv4(uint8_t ip1, | ||||||
|  | @ -1266,26 +1171,13 @@ UdpConnection *sp_udp_open_ipv4(uint8_t ip1, | ||||||
|  * # Examples |  * # Examples | ||||||
|  * |  * | ||||||
|  * ```C |  * ```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, | bool sp_udp_send_command(UdpConnection */*notnull*/ connection, | ||||||
|                          TypedCommand */*notnull*/ command); |                          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]. |  * Sends a [Packet] to the display using the [UdpConnection]. | ||||||
|  * |  * | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| use crate::byte_slice::ByteSlice; | use crate::byte_slice::ByteSlice; | ||||||
| use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, SPBitVec}; | use crate::{heap_drop, heap_move, heap_move_nonnull, SPBitVec}; | ||||||
| use servicepoint::{Bitmap, BitmapCommand, CompressionCode, DataRef, Grid, Origin, Packet}; | use servicepoint::{Bitmap, DataRef, Grid}; | ||||||
| use std::ptr::NonNull; | use std::ptr::NonNull; | ||||||
| 
 | 
 | ||||||
| /// Creates a new [Bitmap] with the specified dimensions.
 | /// Creates a new [Bitmap] with the specified dimensions.
 | ||||||
|  | @ -78,7 +78,7 @@ pub unsafe extern "C" fn sp_bitmap_from_bitvec( | ||||||
|     width: usize, |     width: usize, | ||||||
|     bitvec: NonNull<SPBitVec>, |     bitvec: NonNull<SPBitVec>, | ||||||
| ) -> *mut Bitmap { | ) -> *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) { |     if let Ok(bitmap) = Bitmap::from_bitvec(width, bitvec.0) { | ||||||
|         heap_move(bitmap) |         heap_move(bitmap) | ||||||
|     } else { |     } else { | ||||||
|  | @ -196,29 +196,6 @@ pub unsafe extern "C" fn sp_bitmap_unsafe_data_ref( | ||||||
| pub unsafe extern "C" fn sp_bitmap_into_bitvec( | pub unsafe extern "C" fn sp_bitmap_into_bitvec( | ||||||
|     bitmap: NonNull<Bitmap>, |     bitmap: NonNull<Bitmap>, | ||||||
| ) -> NonNull<SPBitVec> { | ) -> NonNull<SPBitVec> { | ||||||
|     let bitmap = unsafe { heap_remove(bitmap) }; |     let bitmap = unsafe { *Box::from_raw(bitmap.as_ptr()) }; | ||||||
|     heap_move_nonnull(SPBitVec(bitmap.into())) |     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 crate::{heap_drop, heap_move_nonnull, ByteSlice}; | ||||||
| use servicepoint::{BinaryOperation, BitVecCommand, BitVecU8Msb0, CompressionCode, Packet}; | use servicepoint::BitVecU8Msb0; | ||||||
| use std::ptr::NonNull; | use std::ptr::NonNull; | ||||||
| 
 | 
 | ||||||
| /// A vector of bits
 | /// A vector of bits
 | ||||||
|  | @ -146,27 +146,3 @@ pub unsafe extern "C" fn sp_bitvec_unsafe_data_ref( | ||||||
| ) -> ByteSlice { | ) -> ByteSlice { | ||||||
|     unsafe { ByteSlice::from_slice((*bit_vec.as_ptr()).0.as_raw_mut_slice()) } |     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 crate::{heap_drop, heap_move, heap_move_nonnull, ByteSlice}; | ||||||
| use servicepoint::{ | use servicepoint::{Brightness, BrightnessGrid, ByteGrid, DataRef, Grid}; | ||||||
|     Brightness, BrightnessGrid, BrightnessGridCommand, ByteGrid, DataRef, Grid, |  | ||||||
|     Origin, Packet, |  | ||||||
| }; |  | ||||||
| use std::mem::transmute; | use std::mem::transmute; | ||||||
| use std::ptr::NonNull; | use std::ptr::NonNull; | ||||||
| 
 | 
 | ||||||
|  | @ -12,7 +9,7 @@ use std::ptr::NonNull; | ||||||
| ///
 | ///
 | ||||||
| /// # Examples
 | /// # Examples
 | ||||||
| /// ```C
 | /// ```C
 | ||||||
| /// UdpConnection connection = sp_udp_open("127.0.0.1:2342");
 | /// UdpConnection connection = sp_connection_open("127.0.0.1:2342");
 | ||||||
| /// if (connection == NULL)
 | /// if (connection == NULL)
 | ||||||
| ///     return 1;
 | ///     return 1;
 | ||||||
| ///
 | ///
 | ||||||
|  | @ -21,7 +18,7 @@ use std::ptr::NonNull; | ||||||
| /// sp_brightness_grid_set(grid, 1, 1, 10);
 | /// sp_brightness_grid_set(grid, 1, 1, 10);
 | ||||||
| ///
 | ///
 | ||||||
| /// TypedCommand command = sp_command_char_brightness(grid);
 | /// TypedCommand command = sp_command_char_brightness(grid);
 | ||||||
| /// sp_udp_free(connection);
 | /// sp_connection_free(connection);
 | ||||||
| /// ```
 | /// ```
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_brightness_grid_new( | 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); |     const _: () = assert!(size_of::<Brightness>() == 1); | ||||||
| 
 | 
 | ||||||
|     let data = unsafe { (*brightness_grid.as_ptr()).data_ref_mut() }; |     let data = unsafe { (*brightness_grid.as_ptr()).data_ref_mut() }; | ||||||
|     unsafe { |     unsafe { ByteSlice::from_slice(transmute(data)) } | ||||||
|         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(), |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -24,7 +24,7 @@ impl ByteSlice { | ||||||
|         unsafe { std::slice::from_raw_parts(self.start.as_ptr(), self.length) } |         unsafe { std::slice::from_raw_parts(self.start.as_ptr(), self.length) } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub(crate) unsafe fn as_slice_mut(&mut self) -> &mut [u8] { |     pub(crate) unsafe fn as_slice_mut(&self) -> &mut [u8] { | ||||||
|         unsafe { |         unsafe { | ||||||
|             std::slice::from_raw_parts_mut(self.start.as_ptr(), self.length) |             std::slice::from_raw_parts_mut(self.start.as_ptr(), self.length) | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice}; | use crate::{heap_drop, heap_move, heap_move_nonnull, ByteSlice}; | ||||||
| use servicepoint::{CharGrid, CharGridCommand, Grid, Origin, Packet}; | use servicepoint::{CharGrid, Grid}; | ||||||
| use std::ptr::NonNull; | use std::ptr::NonNull; | ||||||
| 
 | 
 | ||||||
| /// Creates a new [CharGrid] with the specified dimensions.
 | /// Creates a new [CharGrid] with the specified dimensions.
 | ||||||
|  | @ -132,24 +132,3 @@ pub unsafe extern "C" fn sp_char_grid_height( | ||||||
| ) -> usize { | ) -> usize { | ||||||
|     unsafe { char_grid.as_ref().height() } |     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
 | /// # Examples
 | ||||||
| ///
 | ///
 | ||||||
| /// ```C
 | /// ```C
 | ||||||
| /// sp_udp_send_command(connection, sp_command_clear());
 | /// sp_connection_send_command(connection, sp_command_clear());
 | ||||||
| /// ```
 | /// ```
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_command_clear() -> NonNull<TypedCommand> { | pub unsafe extern "C" fn sp_command_clear() -> NonNull<TypedCommand> { | ||||||
|  | @ -115,6 +115,10 @@ pub unsafe extern "C" fn sp_command_bitvec( | ||||||
|     operation: BinaryOperation, |     operation: BinaryOperation, | ||||||
| ) -> *mut TypedCommand { | ) -> *mut TypedCommand { | ||||||
|     let bit_vec = unsafe { *Box::from_raw(bit_vec.as_ptr()) }; |     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 { |     let command = servicepoint::BitVecCommand { | ||||||
|         offset, |         offset, | ||||||
|         operation, |         operation, | ||||||
|  | @ -178,6 +182,10 @@ pub unsafe extern "C" fn sp_command_bitmap( | ||||||
|     compression: CompressionCode, |     compression: CompressionCode, | ||||||
| ) -> *mut TypedCommand { | ) -> *mut TypedCommand { | ||||||
|     let bitmap = unsafe { *Box::from_raw(bitmap.as_ptr()) }; |     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 { |     let command = servicepoint::BitmapCommand { | ||||||
|         origin: servicepoint::Origin::new(x, y), |         origin: servicepoint::Origin::new(x, y), | ||||||
|         bitmap, |         bitmap, | ||||||
|  | @ -1,3 +0,0 @@ | ||||||
| mod typed; |  | ||||||
| 
 |  | ||||||
| pub use typed::*; |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| use crate::{heap_drop, heap_move, heap_remove}; | use crate::{heap_drop, heap_move}; | ||||||
| use servicepoint::{Connection, Header, Packet, TypedCommand, UdpConnection}; | use servicepoint::{Connection, Packet, TypedCommand, UdpConnection}; | ||||||
| use std::ffi::{c_char, CStr}; | use std::ffi::{c_char, CStr}; | ||||||
| use std::net::{Ipv4Addr, SocketAddrV4}; | use std::net::{Ipv4Addr, SocketAddrV4}; | ||||||
| use std::ptr::NonNull; | use std::ptr::NonNull; | ||||||
|  | @ -11,9 +11,9 @@ use std::ptr::NonNull; | ||||||
| /// # Examples
 | /// # Examples
 | ||||||
| ///
 | ///
 | ||||||
| /// ```C
 | /// ```C
 | ||||||
| /// UdpConnection connection = sp_udp_open("172.23.42.29:2342");
 | /// UdpConnection connection = sp_connection_open("172.23.42.29:2342");
 | ||||||
| /// if (connection != NULL)
 | /// if (connection != NULL)
 | ||||||
| ///     sp_udp_send_command(connection, sp_command_clear());
 | ///     sp_connection_send_command(connection, sp_command_clear());
 | ||||||
| /// ```
 | /// ```
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_udp_open( | pub unsafe extern "C" fn sp_udp_open( | ||||||
|  | @ -37,9 +37,9 @@ pub unsafe extern "C" fn sp_udp_open( | ||||||
| /// # Examples
 | /// # Examples
 | ||||||
| ///
 | ///
 | ||||||
| /// ```C
 | /// ```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)
 | /// if (connection != NULL)
 | ||||||
| ///     sp_udp_send_command(connection, sp_command_clear());
 | ///     sp_connection_send_command(connection, sp_command_clear());
 | ||||||
| /// ```
 | /// ```
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_udp_open_ipv4( | 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>, |     connection: NonNull<UdpConnection>, | ||||||
|     packet: NonNull<Packet>, |     packet: NonNull<Packet>, | ||||||
| ) -> bool { | ) -> bool { | ||||||
|     let packet = unsafe { heap_remove(packet) }; |     let packet = unsafe { Box::from_raw(packet.as_ptr()) }; | ||||||
|     unsafe { connection.as_ref().send(packet) }.is_ok() |     unsafe { connection.as_ref().send(*packet) }.is_ok() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Sends a [TypedCommand] to the display using the [UdpConnection].
 | /// Sends a [TypedCommand] to the display using the [UdpConnection].
 | ||||||
|  | @ -80,38 +80,18 @@ pub unsafe extern "C" fn sp_udp_send_packet( | ||||||
| /// # Examples
 | /// # Examples
 | ||||||
| ///
 | ///
 | ||||||
| /// ```C
 | /// ```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] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_udp_send_command( | pub unsafe extern "C" fn sp_udp_send_command( | ||||||
|     connection: NonNull<UdpConnection>, |     connection: NonNull<UdpConnection>, | ||||||
|     command: NonNull<TypedCommand>, |     command: NonNull<TypedCommand>, | ||||||
| ) -> bool { | ) -> bool { | ||||||
|     let command = unsafe { heap_remove(command) }; |     let command = *unsafe { Box::from_raw(command.as_ptr()) }; | ||||||
|     unsafe { connection.as_ref().send(command) }.is_ok() |     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].
 | /// Closes and deallocates a [UdpConnection].
 | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_udp_free(connection: NonNull<UdpConnection>) { | 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 crate::{heap_drop, heap_move, heap_move_nonnull, ByteSlice}; | ||||||
| use servicepoint::{Cp437Grid, Cp437GridCommand, DataRef, Grid, Origin, Packet}; | use servicepoint::{Cp437Grid, DataRef, Grid}; | ||||||
| use std::ptr::NonNull; | use std::ptr::NonNull; | ||||||
| 
 | 
 | ||||||
| /// Creates a new [Cp437Grid] with the specified dimensions.
 | /// Creates a new [Cp437Grid] with the specified dimensions.
 | ||||||
|  | @ -132,24 +132,3 @@ pub unsafe extern "C" fn sp_cp437_grid_unsafe_data_ref( | ||||||
| ) -> ByteSlice { | ) -> ByteSlice { | ||||||
|     unsafe { ByteSlice::from_slice((*cp437_grid.as_ptr()).data_ref_mut()) } |     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"
 | //! #include "servicepoint.h"
 | ||||||
| //!
 | //!
 | ||||||
| //! int main(void) {
 | //! 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)
 | //!     if (connection == NULL)
 | ||||||
| //!         return 1;
 | //!         return 1;
 | ||||||
| //!
 | //!
 | ||||||
|  | @ -17,10 +17,10 @@ | ||||||
| //!     sp_bitmap_fill(pixels, true);
 | //!     sp_bitmap_fill(pixels, true);
 | ||||||
| //!
 | //!
 | ||||||
| //!     TypedCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, Uncompressed);
 | //!     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_command_free(command);
 | ||||||
| //!     sp_udp_free(connection);
 | //!     sp_connection_free(connection);
 | ||||||
| //!     return 0;
 | //!     return 0;
 | ||||||
| //! }
 | //! }
 | ||||||
| //! ```
 | //! ```
 | ||||||
|  | @ -30,11 +30,10 @@ pub use crate::bitvec::*; | ||||||
| pub use crate::brightness_grid::*; | pub use crate::brightness_grid::*; | ||||||
| pub use crate::byte_slice::*; | pub use crate::byte_slice::*; | ||||||
| pub use crate::char_grid::*; | pub use crate::char_grid::*; | ||||||
| pub use crate::commands::*; | pub use crate::command::*; | ||||||
| pub use crate::connection::*; | pub use crate::connection::*; | ||||||
| pub use crate::cp437_grid::*; | pub use crate::cp437_grid::*; | ||||||
| pub use crate::packet::*; | pub use crate::packet::*; | ||||||
| pub use servicepoint::CommandCode; |  | ||||||
| use std::ptr::NonNull; | use std::ptr::NonNull; | ||||||
| 
 | 
 | ||||||
| mod bitmap; | mod bitmap; | ||||||
|  | @ -42,7 +41,7 @@ mod bitvec; | ||||||
| mod brightness_grid; | mod brightness_grid; | ||||||
| mod byte_slice; | mod byte_slice; | ||||||
| mod char_grid; | mod char_grid; | ||||||
| mod commands; | mod command; | ||||||
| mod connection; | mod connection; | ||||||
| mod cp437_grid; | mod cp437_grid; | ||||||
| mod packet; | 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>) { | pub(crate) unsafe fn heap_drop<T>(x: NonNull<T>) { | ||||||
|     drop(unsafe { heap_remove(x) }); |     drop(unsafe { Box::from_raw(x.as_ptr()) }); | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub(crate) unsafe fn heap_remove<T>(x: NonNull<T>) -> T { |  | ||||||
|     unsafe { *Box::from_raw(x.as_ptr()) } |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice}; | use crate::{heap_drop, heap_move, heap_move_nonnull, ByteSlice}; | ||||||
| use servicepoint::{CommandCode, Header, Packet, TypedCommand}; | use servicepoint::{Header, Packet, TypedCommand}; | ||||||
| use std::ptr::NonNull; | use std::ptr::NonNull; | ||||||
| 
 | 
 | ||||||
| /// Turns a [TypedCommand] into a [Packet].
 | /// Turns a [TypedCommand] into a [Packet].
 | ||||||
|  | @ -10,7 +10,7 @@ use std::ptr::NonNull; | ||||||
| pub unsafe extern "C" fn sp_packet_from_command( | pub unsafe extern "C" fn sp_packet_from_command( | ||||||
|     command: NonNull<TypedCommand>, |     command: NonNull<TypedCommand>, | ||||||
| ) -> *mut Packet { | ) -> *mut Packet { | ||||||
|     let command = unsafe { heap_remove(command) }; |     let command = unsafe { *Box::from_raw(command.as_ptr()) }; | ||||||
|     if let Ok(packet) = command.try_into() { |     if let Ok(packet) = command.try_into() { | ||||||
|         heap_move(packet) |         heap_move(packet) | ||||||
|     } else { |     } else { | ||||||
|  | @ -65,7 +65,7 @@ pub unsafe extern "C" fn sp_packet_get_header( | ||||||
| pub unsafe extern "C" fn sp_packet_get_payload( | pub unsafe extern "C" fn sp_packet_get_payload( | ||||||
|     packet: NonNull<Packet>, |     packet: NonNull<Packet>, | ||||||
| ) -> ByteSlice { | ) -> 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.
 | /// 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] | #[no_mangle] | ||||||
| pub unsafe extern "C" fn sp_packet_serialize_to( | pub unsafe extern "C" fn sp_packet_serialize_to( | ||||||
|     packet: NonNull<Packet>, |     packet: NonNull<Packet>, | ||||||
|     mut buffer: ByteSlice, |     buffer: ByteSlice, | ||||||
| ) { | ) { | ||||||
|     unsafe { |     unsafe { | ||||||
|         packet.as_ref().serialize_to(buffer.as_slice_mut()); |         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>) { | pub unsafe extern "C" fn sp_packet_free(packet: NonNull<Packet>) { | ||||||
|     unsafe { heap_drop(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