From 32742be6eb9ae965112ec474be0bb12ca3c025db Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sat, 5 Aug 2023 15:58:49 -0500 Subject: [PATCH] Progress: Begin further re-designing of the memory logic. This adds the append and append all functions, respectively. This adds a paramete check to see if width is 0. --- level_0/f_memory/c/memory/array.c | 65 ++++++++++++++++++ level_0/f_memory/c/memory/array.h | 76 +++++++++++++++++++++- level_0/f_memory/c/memory/private-array.c | 4 +- level_0/f_memory/c/memory/private-array.h | 6 +- .../tests/unit/c/test-memory-array_adjust.c | 8 +++ .../tests/unit/c/test-memory-array_decimate_by.c | 9 +++ .../tests/unit/c/test-memory-array_decrease_by.c | 9 +++ .../tests/unit/c/test-memory-array_increase.c | 8 +++ .../tests/unit/c/test-memory-array_increase_by.c | 8 +++ .../tests/unit/c/test-memory-array_resize.c | 32 +++++++++ level_0/f_memory/tests/unit/c/test-memory-resize.c | 14 ++++ level_0/f_memory/tests/unit/c/test-memory.c | 8 +++ level_0/f_memory/tests/unit/c/test-memory.h | 2 + 13 files changed, 244 insertions(+), 5 deletions(-) diff --git a/level_0/f_memory/c/memory/array.c b/level_0/f_memory/c/memory/array.c index 75a6f04..cfc1341 100644 --- a/level_0/f_memory/c/memory/array.c +++ b/level_0/f_memory/c/memory/array.c @@ -8,6 +8,7 @@ extern "C" { #ifndef _di_f_memory_array_adjust_ f_status_t f_memory_array_adjust(const f_number_unsigned_t length, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size) { #ifndef _di_level_0_parameter_checking_ + if (!width) return F_status_set_error(F_parameter); if (!array) return F_status_set_error(F_parameter); if (!used) return F_status_set_error(F_parameter); if (!size) return F_status_set_error(F_parameter); @@ -19,9 +20,69 @@ extern "C" { } #endif // _di_f_memory_array_adjust_ +#ifndef _di_f_memory_array_append_ + f_status_t f_memory_array_append(const void * const source, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size) { + #ifndef _di_level_0_parameter_checking_ + if (!width) return F_status_set_error(F_parameter); + if (!array) return F_status_set_error(F_parameter); + if (!used) return F_status_set_error(F_parameter); + if (!size) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (*used >= F_number_t_size_unsigned_d) return F_status_set_error(F_array_too_large); + + { + const f_number_unsigned_t length = *used + F_memory_default_allocation_small_d; + + if (length > *size) { + if (length > F_number_t_size_unsigned_d) return F_status_set_error(F_array_too_large); + + const f_status_t status = private_f_memory_array_resize(length, width, array, used, size); + if (F_status_is_error(status)) return status; + } + } + + memcpy((*array) + (*used)++, source, width); + + return F_none; + } +#endif // _di_f_memory_array_append_ + +#ifndef _di_f_memory_array_append_all_ + f_status_t f_memory_array_append_all(const void * const sources, const f_number_unsigned_t amount, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size) { + #ifndef _di_level_0_parameter_checking_ + if (!width) return F_status_set_error(F_parameter); + if (!array) return F_status_set_error(F_parameter); + if (!used) return F_status_set_error(F_parameter); + if (!size) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!amount) return F_data_not; + if (*used >= F_number_t_size_unsigned_d) return F_status_set_error(F_array_too_large); + + { + const f_number_unsigned_t length = *used + amount; + + if (length > *size) { + if (length > F_number_t_size_unsigned_d) return F_status_set_error(F_array_too_large); + + const f_status_t status = private_f_memory_array_resize(length, width, array, used, size); + if (F_status_is_error(status)) return status; + } + } + + memcpy(*array + *used, sources, width * amount); + + *used += amount; + + return F_none; + } +#endif // _di_f_memory_array_append_all_ + #ifndef _di_f_memory_array_decimate_by_ f_status_t f_memory_array_decimate_by(const f_number_unsigned_t amount, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size) { #ifndef _di_level_0_parameter_checking_ + if (!width) return F_status_set_error(F_parameter); if (!array) return F_status_set_error(F_parameter); if (!used) return F_status_set_error(F_parameter); if (!size) return F_status_set_error(F_parameter); @@ -36,6 +97,7 @@ extern "C" { #ifndef _di_f_memory_array_decrease_by_ f_status_t f_memory_array_decrease_by(const f_number_unsigned_t amount, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size) { #ifndef _di_level_0_parameter_checking_ + if (!width) return F_status_set_error(F_parameter); if (!array) return F_status_set_error(F_parameter); if (!used) return F_status_set_error(F_parameter); if (!size) return F_status_set_error(F_parameter); @@ -50,6 +112,7 @@ extern "C" { #ifndef _di_f_memory_array_increase_ f_status_t f_memory_array_increase(const f_number_unsigned_t step, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size) { #ifndef _di_level_0_parameter_checking_ + if (!width) return F_status_set_error(F_parameter); if (!array) return F_status_set_error(F_parameter); if (!used) return F_status_set_error(F_parameter); if (!size) return F_status_set_error(F_parameter); @@ -76,6 +139,7 @@ extern "C" { #ifndef _di_f_memory_array_increase_by_ f_status_t f_memory_array_increase_by(const f_number_unsigned_t amount, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size) { #ifndef _di_level_0_parameter_checking_ + if (!width) return F_status_set_error(F_parameter); if (!array) return F_status_set_error(F_parameter); if (!used) return F_status_set_error(F_parameter); if (!size) return F_status_set_error(F_parameter); @@ -100,6 +164,7 @@ extern "C" { #ifndef _di_f_memory_array_resize_ f_status_t f_memory_array_resize(const f_number_unsigned_t length, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size) { #ifndef _di_level_0_parameter_checking_ + if (!width) return F_status_set_error(F_parameter); if (!array) return F_status_set_error(F_parameter); if (!used) return F_status_set_error(F_parameter); if (!size) return F_status_set_error(F_parameter); diff --git a/level_0/f_memory/c/memory/array.h b/level_0/f_memory/c/memory/array.h index 29ef8a0..d5baae2 100644 --- a/level_0/f_memory/c/memory/array.h +++ b/level_0/f_memory/c/memory/array.h @@ -27,6 +27,7 @@ extern "C" { * @param width * The size of the structure represented by array. * The word "width" is used due to conflicts of already using "length" and "size". + * Must not be 0. * @param array * The structure.array to resize. * @param used @@ -46,6 +47,74 @@ extern "C" { #endif // _di_f_memory_array_adjust_ /** + * Append the single source onto the destination array. + * + * This function is only useful for simple structures of the form "{ array, used, size }" where the array is a simple type. + * If the simple type that is "array" requires additional memory manipulation on allocation or de-allocation, then do not use this function. + * + * @param source + * The source structure to copy from. + * @param width + * The size of the structure represented by array. + * The word "width" is used due to conflicts of already using "length" and "size". + * Must not be 0. + * @param array + * The structure.array destination. + * @param used + * The structure.used destination. + * @param size + * The structure.size destination. + * + * @return + * F_none on success. + * + * F_array_too_large (with error bit) if the new array length is too large. + * F_memory_not (with error bit) on out of memory. + * F_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_memory_array_append_ + extern f_status_t f_memory_array_append(const void * const source, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size); +#endif // _di_f_memory_array_append_ + +/** + * Append the single source onto the destination array. + * + * This function is only useful for simple structures of the form "{ array, used, size }" where the array is a simple type. + * If the simple type that is "array" requires additional memory manipulation on allocation or de-allocation, then do not use this function. + * + * Warning: This default implementation of this function uses multiplication between the amount and the width. + * Be careful that the resulting multiplication does not overflow f_number_unsigned_t. + * + * @param sources + * The source structure to copy from. + * This is generally a structure.array value. + * @param amount + * The total length of the sources to copy. + * The is generally the structure.used value. + * @param width + * The size of the structure represented by array. + * The word "width" is used due to conflicts of already using "length" and "size". + * Must not be 0. + * @param array + * The structure.array destination. + * @param used + * The structure.used destination. + * @param size + * The structure.size destination. + * + * @return + * F_none on success. + * F_data_not if amount is 0. + * + * F_array_too_large (with error bit) if the new array length is too large. + * F_memory_not (with error bit) on out of memory. + * F_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_memory_array_append_all_ + extern f_status_t f_memory_array_append_all(const void * const sources, const f_number_unsigned_t amount, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size); +#endif // _di_f_memory_array_append_all_ + +/** * Resize the memory array to a smaller size. * * This will resize making the array smaller based on (size - given length). @@ -60,6 +129,7 @@ extern "C" { * @param width * The size of the structure represented by array. * The word "width" is used due to conflicts of already using "length" and "size". + * Must not be 0. * @param array * The structure.array to resize. * @param used @@ -92,6 +162,7 @@ extern "C" { * @param width * The size of the structure represented by array. * The word "width" is used due to conflicts of already using "length" and "size". + * Must not be 0. * @param array * The structure.array to resize. * @param used @@ -124,6 +195,7 @@ extern "C" { * @param width * The size of the structure represented by array. * The word "width" is used due to conflicts of already using "length" and "size". + * Must not be 0. * @param array * The structure.array to resize. * @param used @@ -136,7 +208,7 @@ extern "C" { * F_data_not on success, but there is no reason to increase size (used + 1 <= size). * * F_array_too_large (with error bit) if the new array length is too large. - * F_memory_not (with error bit) on out of memory. + * F_memory_not (with error bit) on out of memory.. * F_parameter (with error bit) if a parameter is invalid. */ #ifndef _di_f_memory_array_increase_ @@ -158,6 +230,7 @@ extern "C" { * @param width * The size of the structure represented by array. * The word "width" is used due to conflicts of already using "length" and "size". + * Must not be 0. * @param array * The structure.array to resize. * @param used @@ -188,6 +261,7 @@ extern "C" { * @param width * The size of the structure represented by array. * The word "width" is used due to conflicts of already using "length" and "size". + * Must not be 0. * @param array * The structure.array to resize. * @param used diff --git a/level_0/f_memory/c/memory/private-array.c b/level_0/f_memory/c/memory/private-array.c index 5b96940..daf0d2f 100644 --- a/level_0/f_memory/c/memory/private-array.c +++ b/level_0/f_memory/c/memory/private-array.c @@ -22,7 +22,7 @@ extern "C" { } #endif // !defined(_di_f_memory_array_adjust_) || !defined(_di_f_memory_array_decimate_by_) -#if !defined(_di_f_memory_array_decrease_by_) || !defined(_di_f_memory_array_increase_) || !defined(_di_f_memory_array_increase_by_) || !defined(_di_f_memory_array_resize_) +#if !defined(_di_f_memory_array_append_) || !defined(_di_f_memory_array_append_all_) || !defined(_di_f_memory_array_decrease_by_) || !defined(_di_f_memory_array_increase_) || !defined(_di_f_memory_array_increase_by_) || !defined(_di_f_memory_array_resize_) f_status_t private_f_memory_array_resize(const f_number_unsigned_t length, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size) { const f_status_t status = private_f_memory_resize(*size, length, width, array); @@ -36,7 +36,7 @@ extern "C" { return F_none; } -#endif // !defined(_di_f_memory_array_decrease_by_) || !defined(_di_f_memory_array_increase_) || !defined(_di_f_memory_array_increase_by_) || !defined(_di_f_memory_array_resize_) +#endif // !defined(_di_f_memory_array_append_) || !defined(_di_f_memory_array_append_all_) || !defined(_di_f_memory_array_decrease_by_) || !defined(_di_f_memory_array_increase_) || !defined(_di_f_memory_array_increase_by_) || !defined(_di_f_memory_array_resize_) #ifdef __cplusplus } // extern "C" diff --git a/level_0/f_memory/c/memory/private-array.h b/level_0/f_memory/c/memory/private-array.h index 261f860..6172eeb 100644 --- a/level_0/f_memory/c/memory/private-array.h +++ b/level_0/f_memory/c/memory/private-array.h @@ -67,15 +67,17 @@ extern "C" { * * Errors (with error bit) from: f_memory_resize(). * + * @see f_memory_array_append() + * @see f_memory_array_append_all() * @see f_memory_array_decrease_by() * @see f_memory_array_increase() * @see f_memory_array_increase_by() * @see f_memory_array_resize() * @see f_memory_resize() */ -#if !defined(_di_f_memory_array_decrease_by_) || !defined(_di_f_memory_array_increase_) || !defined(_di_f_memory_array_increase_by_) || !defined(_di_f_memory_array_resize_) +#if !defined(_di_f_memory_array_append_) || !defined(_di_f_memory_array_append_all_) || !defined(_di_f_memory_array_decrease_by_) || !defined(_di_f_memory_array_increase_) || !defined(_di_f_memory_array_increase_by_) || !defined(_di_f_memory_array_resize_) extern f_status_t private_f_memory_array_resize(const f_number_unsigned_t length, const size_t width, void ** array, f_number_unsigned_t * const used, f_number_unsigned_t * const size) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_memory_array_decrease_by_) || !defined(_di_f_memory_array_increase_) || !defined(_di_f_memory_array_increase_by_) || !defined(_di_f_memory_array_resize_) +#endif // !defined(_di_f_memory_array_append_) || !defined(_di_f_memory_array_append_all_) || !defined(_di_f_memory_array_decrease_by_) || !defined(_di_f_memory_array_increase_) || !defined(_di_f_memory_array_increase_by_) || !defined(_di_f_memory_array_resize_) #ifdef __cplusplus } // extern "C" diff --git a/level_0/f_memory/tests/unit/c/test-memory-array_adjust.c b/level_0/f_memory/tests/unit/c/test-memory-array_adjust.c index e41538b..602545a 100644 --- a/level_0/f_memory/tests/unit/c/test-memory-array_adjust.c +++ b/level_0/f_memory/tests/unit/c/test-memory-array_adjust.c @@ -42,6 +42,14 @@ void test__f_memory_array_adjust__parameter_checking(void **state) { assert_int_equal(data.size, 0); } + { + const f_status_t status = f_memory_array_adjust(length, 0, (void **) &data.array, &data.used, &data.size); + + assert_int_equal(status, F_status_set_error(F_parameter)); + assert_int_equal(data.used, 0); + assert_int_equal(data.size, 0); + } + assert_null(data.array); } diff --git a/level_0/f_memory/tests/unit/c/test-memory-array_decimate_by.c b/level_0/f_memory/tests/unit/c/test-memory-array_decimate_by.c index 50eaf74..fabe671 100644 --- a/level_0/f_memory/tests/unit/c/test-memory-array_decimate_by.c +++ b/level_0/f_memory/tests/unit/c/test-memory-array_decimate_by.c @@ -41,6 +41,15 @@ void test__f_memory_array_decimate_by__parameter_checking(void **state) { assert_int_equal(data.size, 0); } + { + const f_status_t status = f_memory_array_decimate_by(length, 0, (void **) &data.array, &data.used, &data.size); + + assert_int_equal(status, F_size_not); + assert_int_equal(data.array, 0); + assert_int_equal(data.used, 0); + assert_int_equal(data.size, 0); + } + assert_null(data.array); } diff --git a/level_0/f_memory/tests/unit/c/test-memory-array_decrease_by.c b/level_0/f_memory/tests/unit/c/test-memory-array_decrease_by.c index 2d9e320..7a2aba5 100644 --- a/level_0/f_memory/tests/unit/c/test-memory-array_decrease_by.c +++ b/level_0/f_memory/tests/unit/c/test-memory-array_decrease_by.c @@ -41,6 +41,15 @@ void test__f_memory_array_decrease_by__parameter_checking(void **state) { assert_int_equal(data.size, 0); } + { + const f_status_t status = f_memory_array_decrease_by(length, 0, (void **) &data.array, &data.used, &data.size); + + assert_int_equal(status, F_size_not); + assert_int_equal(data.array, 0); + assert_int_equal(data.used, 0); + assert_int_equal(data.size, 0); + } + assert_null(data.array); } diff --git a/level_0/f_memory/tests/unit/c/test-memory-array_increase.c b/level_0/f_memory/tests/unit/c/test-memory-array_increase.c index 924016f..4beca73 100644 --- a/level_0/f_memory/tests/unit/c/test-memory-array_increase.c +++ b/level_0/f_memory/tests/unit/c/test-memory-array_increase.c @@ -41,6 +41,14 @@ void test__f_memory_array_increase__parameter_checking(void **state) { assert_int_equal(data.size, 0); } + { + const f_status_t status = f_memory_array_increase(length, 0, (void **) &data.array, &data.used, &data.size); + + assert_int_equal(status, F_status_set_error(F_parameter)); + assert_int_equal(data.used, 0); + assert_int_equal(data.size, 0); + } + assert_null(data.array); } diff --git a/level_0/f_memory/tests/unit/c/test-memory-array_increase_by.c b/level_0/f_memory/tests/unit/c/test-memory-array_increase_by.c index 1240d95..7aaca88 100644 --- a/level_0/f_memory/tests/unit/c/test-memory-array_increase_by.c +++ b/level_0/f_memory/tests/unit/c/test-memory-array_increase_by.c @@ -80,6 +80,14 @@ void test__f_memory_array_increase_by__returns_data_not(void **state) { assert_int_equal(data.size, length); } + { + const f_status_t status = f_memory_array_increase_by(length, 0, (void **) &data.array, &data.used, &data.size); + + assert_int_equal(status, F_status_set_error(F_parameter)); + assert_int_equal(data.used, 0); + assert_int_equal(data.size, 0); + } + free((void *) data.array); } diff --git a/level_0/f_memory/tests/unit/c/test-memory-array_resize.c b/level_0/f_memory/tests/unit/c/test-memory-array_resize.c index 16787c1..86d65b0 100644 --- a/level_0/f_memory/tests/unit/c/test-memory-array_resize.c +++ b/level_0/f_memory/tests/unit/c/test-memory-array_resize.c @@ -18,6 +18,38 @@ void test__f_memory_array_resize__parameter_checking(void **state) { assert_int_equal(data.size, 0); } + { + const f_status_t status = f_memory_array_resize(length, sizeof(int), 0, &data.used, &data.size); + + assert_int_equal(status, F_status_set_error(F_parameter)); + assert_int_equal(data.used, 0); + assert_int_equal(data.size, 0); + } + + { + const f_status_t status = f_memory_array_resize(length, sizeof(int), (void **) &data.array, 0, &data.size); + + assert_int_equal(status, F_status_set_error(F_parameter)); + assert_int_equal(data.used, 0); + assert_int_equal(data.size, 0); + } + + { + const f_status_t status = f_memory_array_resize(length, sizeof(int), (void **) &data.array, &data.used, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + assert_int_equal(data.used, 0); + assert_int_equal(data.size, 0); + } + + { + const f_status_t status = f_memory_array_resize(length, 0, (void **) &data.array, &data.used, &data.size); + + assert_int_equal(status, F_status_set_error(F_parameter)); + assert_int_equal(data.used, 0); + assert_int_equal(data.size, 0); + } + assert_null(data.array); } diff --git a/level_0/f_memory/tests/unit/c/test-memory-resize.c b/level_0/f_memory/tests/unit/c/test-memory-resize.c index 4fa5c6c..d1b44b0 100644 --- a/level_0/f_memory/tests/unit/c/test-memory-resize.c +++ b/level_0/f_memory/tests/unit/c/test-memory-resize.c @@ -20,6 +20,20 @@ void test__f_memory_resize__parameter_checking(void **state) { } } +void test__f_memory_array_resize__returns_size_not(void **state) { + + test_memory_array_t data = test_memory_array_t_initialize; + + { + const f_status_t status = f_memory_array_resize(1, 0, (void **) &data.array, &data.used, &data.size); + + assert_int_equal(status, F_size_not); + assert_int_equal(data.array, 0); + assert_int_equal(data.used, 0); + assert_int_equal(data.size, 0); + } +} + void test__f_memory_resize__works(void **state) { uint16_t *data = 0; diff --git a/level_0/f_memory/tests/unit/c/test-memory.c b/level_0/f_memory/tests/unit/c/test-memory.c index 16e96c5..c15dcb9 100644 --- a/level_0/f_memory/tests/unit/c/test-memory.c +++ b/level_0/f_memory/tests/unit/c/test-memory.c @@ -35,16 +35,22 @@ int main(void) { cmocka_unit_test(test__f_memory_resize__works), cmocka_unit_test(test__f_memory_array_adjust__returns_array_too_large), + cmocka_unit_test(test__f_memory_array_append__returns_array_too_large), + cmocka_unit_test(test__f_memory_array_append_all__returns_array_too_large), cmocka_unit_test(test__f_memory_array_increase__returns_array_too_large), cmocka_unit_test(test__f_memory_array_increase_by__returns_array_too_large), cmocka_unit_test(test__f_memory_array_resize__returns_array_too_large), + cmocka_unit_test(test__f_memory_array_append__returns_data_not), + cmocka_unit_test(test__f_memory_array_append_all__returns_data_not), cmocka_unit_test(test__f_memory_array_decimate_by__returns_data_not), cmocka_unit_test(test__f_memory_array_decrease_by__returns_data_not), cmocka_unit_test(test__f_memory_array_increase__returns_data_not), cmocka_unit_test(test__f_memory_array_increase_by__returns_data_not), cmocka_unit_test(test__f_memory_array_adjust__works), + cmocka_unit_test(test__f_memory_array_append__works), + cmocka_unit_test(test__f_memory_array_append_all__works), cmocka_unit_test(test__f_memory_array_decimate_by__works), cmocka_unit_test(test__f_memory_array_decrease_by__works), cmocka_unit_test(test__f_memory_array_increase__works), @@ -59,6 +65,8 @@ int main(void) { cmocka_unit_test(test__f_memory_resize__parameter_checking), cmocka_unit_test(test__f_memory_array_adjust__parameter_checking), + cmocka_unit_test(test__f_memory_array_append__parameter_checking), + cmocka_unit_test(test__f_memory_array_append_all__parameter_checking), cmocka_unit_test(test__f_memory_array_decimate_by__parameter_checking), cmocka_unit_test(test__f_memory_array_decrease_by__parameter_checking), cmocka_unit_test(test__f_memory_array_increase__parameter_checking), diff --git a/level_0/f_memory/tests/unit/c/test-memory.h b/level_0/f_memory/tests/unit/c/test-memory.h index 6f792d2..605ab61 100644 --- a/level_0/f_memory/tests/unit/c/test-memory.h +++ b/level_0/f_memory/tests/unit/c/test-memory.h @@ -25,6 +25,8 @@ // Test includes. #include "test-memory-adjust.h" #include "test-memory-array_adjust.h" +#include "test-memory-array_append.h" +#include "test-memory-array_append_all.h" #include "test-memory-array_decimate_by.h" #include "test-memory-array_decrease_by.h" #include "test-memory-array_increase.h" -- 1.8.3.1