This adds the append and append all functions, respectively.
This adds a paramete check to see if width is 0.
#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);
}
#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);
#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);
#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);
#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);
#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);
* @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
#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).
* @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
* @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
* @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
* 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_
* @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
* @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
}
#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);
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"
*
* 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"
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
}
}
+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;
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),
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),
// 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"