From de3ac20422850ea919a3c737c112eb3ead9b142a Mon Sep 17 00:00:00 2001 From: Eric-Paul Ickhorn Date: Fri, 1 Dec 2023 16:36:36 +0100 Subject: [PATCH] Added memory functions (not tested) --- code/exports/librr/memory.h | 41 +++++++++++++++++++++++++++++ code/src-c/memory.c | 51 +++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 code/exports/librr/memory.h create mode 100644 code/src-c/memory.c diff --git a/code/exports/librr/memory.h b/code/exports/librr/memory.h new file mode 100644 index 0000000..5fcbbeb --- /dev/null +++ b/code/exports/librr/memory.h @@ -0,0 +1,41 @@ + +#ifndef RR_RUNES_H +#define RR_RUNES_H + +#include + + +/// @brief Tests if two memory regions overlap partially or completely. +/// @param block1 Block to check for overlapping with block2. +// If the address of this block is higher than that of block2, the blocks will be swapped internally. +/// @param length1 The length of the first block. +/// @param block2 The second block to check for overlapping. +/// @param length2 +/// @return Whether the two blocks overlap. +bool_t rr_mem_overlap(void *block1, usz_t length1, void *block2, usz_t length2); + +/// @brief Checks if two memory blocks contain the equal data. +/// @param block1 Address of the data to be checked for equality with 'block2' +/// @param block2 Address of the other memory block. In cases where there is a clear correct version, +/// this should be the correct data to be checked against. +/// @param count How many bytes will be checked. +/// @return +bool_t rr_memequ(void *block1, void *block2, usz_t count); + +/// @brief Sets all bytes in a memory region all to one byte +/// @param destination Address to the memory region to fill with one byte +/// @param count Number of bytes to set; length of 'destination' +/// @param value Value to write to every bte of 'destination'. +void rr_memset(void *destination, usz_t count, u8_t value); + +/// @brief Repeats a sequence until a number of bytes was filled, potentially only writing a sequence half-way. +/// @attention The sequence cannot be contained in the destination. +/// @param destination Address in memory in which the sequence will be repeated. +/// @param num_bytes How many bytes of the destination should be filled. The last sequence can be partially finished. +/// @param sequence Sequence of bytes which will be written to destination. +/// @param len_sequence Length of 'sequence' +/// @return The number of attempted or partial repetitions which have been performed. +usz_t rr_memrep(void *destination, usz_t num_bytes, void *sequence, usz_t len_sequence); + + +#endif // LIBRR_RUNES_H diff --git a/code/src-c/memory.c b/code/src-c/memory.c new file mode 100644 index 0000000..477aa6a --- /dev/null +++ b/code/src-c/memory.c @@ -0,0 +1,51 @@ +#include + +bool_t rr_mem_overlap(void *block1, usz_t length1, void *block2, usz_t length2) +{ + // Make block1 always be before block2 + if(block1 > block2) + { + void *block_backup = block2; + usz_t length_backup = length2; + block2 = block1; + length2 = length1; + block1 = block_backup; + length1 = length_backup; + } + usz_t start1 = (usz_t) block1; + usz_t start2 = (usz_t) block2; + usz_t end2 = start2 + length2; + + if(end2 > start1) + { + return TRUE; + } + return FALSE; +} + +bool_t rr_memequ(void *block1, void *block2, usz_t count) +{ + u8_t *block1_8 = block1; + u8_t *block2_8 = block2; + for(usz_t index = 0; index < count; ++index) + if(block1_8[index] != block2_8[index]) return FALSE; + return TRUE; +} + +void rr_memset(void *destination, usz_t count, u8_t value) +{ + u8_t *destination_8 = destination; + for(usz_t index = 0; index < count; ++index) + destination_8[index] = value; +} + +usz_t rr_memrep(void *destination, usz_t num_bytes, void *sequence, usz_t len_sequence) +{ + if(rr_mem_overlap(destination, num_bytes, sequence, len_sequence)) return 0; + u8_t *destination_8 = destination; + u8_t *sequence_8 = sequence; + for(usz_t index = 0; index < num_bytes; ++index) + destination_8[index] = sequence_8[index % len_sequence]; + return (num_bytes / len_sequence) // How many full repetitions are performed + + ((num_bytes % len_sequence) != 0); // One more if a partial repetiton is done +}