]> Kevux Git Server - fll/commitdiff
Progress: Begin further re-designing of the memory logic.
authorKevin Day <kevin@kevux.org>
Sat, 5 Aug 2023 20:58:49 +0000 (15:58 -0500)
committerKevin Day <kevin@kevux.org>
Sat, 5 Aug 2023 21:00:24 +0000 (16:00 -0500)
This adds the append and append all functions, respectively.
This adds a paramete check to see if width is 0.

13 files changed:
level_0/f_memory/c/memory/array.c
level_0/f_memory/c/memory/array.h
level_0/f_memory/c/memory/private-array.c
level_0/f_memory/c/memory/private-array.h
level_0/f_memory/tests/unit/c/test-memory-array_adjust.c
level_0/f_memory/tests/unit/c/test-memory-array_decimate_by.c
level_0/f_memory/tests/unit/c/test-memory-array_decrease_by.c
level_0/f_memory/tests/unit/c/test-memory-array_increase.c
level_0/f_memory/tests/unit/c/test-memory-array_increase_by.c
level_0/f_memory/tests/unit/c/test-memory-array_resize.c
level_0/f_memory/tests/unit/c/test-memory-resize.c
level_0/f_memory/tests/unit/c/test-memory.c
level_0/f_memory/tests/unit/c/test-memory.h

index 75a6f04d265c755531361d3f96c764efeeacafd2..cfc13415746d020e77f5d1536443c305445a7305 100644 (file)
@@ -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);
index 29ef8a0e1a04049d605c3f9b57ae5be3e5fbd62a..d5baae224f19d753e6f8eda52ad2e83ec6694903 100644 (file)
@@ -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
index 5b96940084e937487ee572c0511f31ac1f4d8e4c..daf0d2f25d4e042bcfcb20f794914febd084201d 100644 (file)
@@ -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"
index 261f86034dbf428c112e2e8e2a9d315bd88ab4c7..6172eebf924996f3119adebc708c1f5a29124f91 100644 (file)
@@ -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"
index e41538bde589fac22eca23ea838bb2f5138ac339..602545ae62944ac01f8321f9c44b12c4bf59635f 100644 (file)
@@ -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);
 }
 
index 50eaf74606ad76759c9ff34263899e89e098855f..fabe671357ce2aee61b906f213a7b61bd985b8ff 100644 (file)
@@ -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);
 }
 
index 2d9e3204608775af502282e08d139c47b57c16f6..7a2aba57019ae4c56c27e5aba7edac072a6d78c3 100644 (file)
@@ -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);
 }
 
index 924016fd5034c6c9114ecfde18826bc33eb16f9b..4beca7354c26b6994d1e8886e1f3d22c643e4db2 100644 (file)
@@ -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);
 }
 
index 1240d9553c6de808f888fe478282a9faa1fc0de7..7aaca88df7dc8a1ed18ba1384807f1a005358574 100644 (file)
@@ -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);
 }
 
index 16787c1a6f91668115099b94e5d65171f46a30d1..86d65b0f5988c682494d95a03800e7d0dd2a00cd 100644 (file)
@@ -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);
 }
 
index 4fa5c6cdb07fef59fc158a132199b0c94d09f158..d1b44b0323c7a2577b65c047895b09aa9b1d0c40 100644 (file)
@@ -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;
index 16e96c5f4f60e87b75d4f057a34289a4399a749d..c15dcb9e1512b81373e0eccc946ab161f49bcd5c 100644 (file)
@@ -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),
index 6f792d2f4d3697903facad45e0f70a1ed4497d47..605ab61911a5e0ab7b1fd25f285c43779bdf205b 100644 (file)
@@ -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"