/** * Copyright (c) 2025 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "memory.h" #include "assert/assert.h" #include "util/math.h" void * memoryAllocate(const size_t size) { assertTrue(size > 0, "Cannot allocate 0 bytes of memory."); void *ptr = malloc(size); assertNotNull(ptr, "Memory allocation failed."); return ptr; } void memoryFree(void *ptr) { assertNotNull(ptr, "Cannot free NULL memory."); free(ptr); } void memoryCopy(void *dest, const void *src, const size_t size) { assertNotNull(dest, "Cannot copy to NULL memory."); assertNotNull(src, "Cannot copy from NULL memory."); assertTrue(size > 0, "Cannot copy 0 bytes of memory."); assertTrue(dest != src, "Cannot copy memory to itself."); // Check for overlapping regions assertTrue( ((uint8_t*)dest + size <= (uint8_t*)src) || ((uint8_t*)src + size <= (uint8_t*)dest), "Source and destination memory regions overlap." ); memcpy(dest, src, size); } void memorySet(void *dest, const uint8_t value, const size_t size) { assertNotNull(dest, "Cannot set NULL memory."); assertTrue(size > 0, "Cannot set 0 bytes of memory."); memset(dest, value, size); } void memoryZero(void *dest, const size_t size) { memorySet(dest, 0, size); } void memoryCopyRangeSafe( void *dest, const void *start, const void *end, const size_t sizeMax ) { assertFalse(start == end, "Start and end pointers are the same."); assertTrue(end > start, "End pointer is not after start pointer."); size_t copy = (size_t)end - (size_t)start; assertTrue(copy <= sizeMax, "Size of memory to copy is too large."); memoryCopy(dest, start, copy); } void memoryMove(void *dest, const void *src, const size_t size) { assertNotNull(dest, "Cannot move to NULL memory."); assertNotNull(src, "Cannot move from NULL memory."); assertTrue(size > 0, "Cannot move 0 bytes of memory."); assertTrue(dest != src, "Cannot move memory to itself."); memmove(dest, src, size); } int_t memoryCompare( const void *a, const void *b, const size_t size ) { assertNotNull(a, "Cannot compare NULL memory."); assertNotNull(b, "Cannot compare NULL memory."); assertTrue(size > 0, "Cannot compare 0 bytes of memory."); return memcmp(a, b, size); } void memoryReallocate(void **ptr, const size_t size) { assertNotNull(ptr, "Cannot reallocate NULL pointer."); assertTrue(size > 0, "Cannot reallocate to 0 bytes of memory."); void *newPointer = memoryAllocate(size); assertNotNull(newPointer, "Memory reallocation failed."); memoryFree(*ptr); *ptr = newPointer; } void memoryResize(void **ptr, const size_t oldSize, const size_t newSize) { assertNotNull(ptr, "Cannot resize NULL pointer."); assertTrue(newSize > 0, "Cannot resize to 0 bytes of memory."); assertTrue(oldSize > 0, "Old size cannot be 0 bytes."); if(newSize == oldSize) return; void *newPointer = memoryAllocate(newSize); assertNotNull(newPointer, "Memory resizing failed."); memoryCopy(newPointer, *ptr, mathMin(oldSize, newSize)); memoryFree(*ptr); *ptr = newPointer; }