]> Kevux Git Server - fll/commitdiff
Update: add snatch apart functions and improve logic of fss snatch functions
authorKevin Day <thekevinday@gmail.com>
Sat, 9 May 2020 04:28:31 +0000 (23:28 -0500)
committerKevin Day <thekevinday@gmail.com>
Sat, 9 May 2020 04:28:31 +0000 (23:28 -0500)
The snatch apart is to create separate sets of strings instead of merging them.
The snatch mash apart will mash all dynamic strings for all content for a single object but use separate strings for each separate object.

I accidentally, or perhaps habitually, used break when return is better when handling errors.
Make sure to document f_string_max_size as a possible return result.

level_2/fll_fss/c/fss.c
level_2/fll_fss/c/fss.h

index 55004704ffd6c69694ee7a622e064d6d8113178e..12f4a58300a7ecfd93607b5a843c5223f46e0e07 100644 (file)
@@ -25,28 +25,27 @@ extern "C" {
       length_object = (objects.array[i].stop - objects.array[i].start) + 1;
 
       for (j = 0; j < size; j++) {
-        if (fl_string_compare_trim(buffer.string + objects.array[i].start, names[j], length_object, lengths[j]) == f_equal_to) {
-          if (values[j]->used == 0) {
-            for (k = 0; k < contents.array[i].used; k++) {
-              status = fl_string_dynamic_partial_append_nulless(buffer, contents.array[i].array[k], values[j]);
+        status = fl_string_compare_trim(buffer.string + objects.array[i].start, names[j], length_object, lengths[j]);
 
-              if (f_status_is_error(status)) break;
-            } // for
+        if (f_status_is_error(status)) return status;
+        if (status == f_not_equal_to) continue;
 
-            if (f_status_is_error(status)) break;
-          }
+        if (values[j]->used == 0) {
+          for (k = 0; k < contents.array[i].used; k++) {
+            status = fl_string_dynamic_partial_append_nulless(buffer, contents.array[i].array[k], values[j]);
+
+            if (f_status_is_error(status)) return status;
+          } // for
         }
       } // for
-
-      if (f_status_is_error(status)) break;
     } // for
 
     return status;
   }
 #endif // _di_fll_fss_snatch_
 
-#ifndef _di_fll_fss_snatch_together_
-  f_return_status fll_fss_snatch_together(const f_string_dynamic buffer, const f_fss_objects objects, const f_fss_contents contents, const f_string names[], const f_string_length lengths[], f_string_dynamic *values[], const f_string_length size) {
+#ifndef _di_fll_fss_snatch_apart_
+  f_return_status fll_fss_snatch_apart(const f_string_dynamic buffer, const f_fss_objects objects, const f_fss_contents contents, const f_string names[], const f_string_length lengths[], f_string_dynamics *values[], const f_string_length size) {
     #ifndef _di_level_2_parameter_checking_
       if (size == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_2_parameter_checking_
@@ -66,18 +65,64 @@ extern "C" {
       length_object = (objects.array[i].stop - objects.array[i].start) + 1;
 
       for (j = 0; j < size; j++) {
-        if (fl_string_compare_trim(buffer.string + objects.array[i].start, names[j], length_object, lengths[j]) == f_equal_to) {
-          for (k = 0; k < contents.array[i].used; k++) {
-            status = fl_string_dynamic_partial_append_nulless(buffer, contents.array[i].array[k], values[j]);
+        status = fl_string_compare_trim(buffer.string + objects.array[i].start, names[j], length_object, lengths[j]);
 
-            if (f_status_is_error(status)) break;
-          } // for
+        if (f_status_is_error(status)) return status;
+        if (status == f_not_equal_to) continue;
+
+        if (values[j]->used + contents.array[i].used > f_string_max_size) return f_status_set_error(f_buffer_too_large);
 
-          if (f_status_is_error(status)) break;
+        if (values[j]->used + contents.array[i].used > values[j]->used) {
+          f_macro_string_dynamics_resize(status, (*values[j]), values[j]->used + contents.array[i].used);
+          if (f_status_is_error(status)) return status;
         }
+
+        for (k = 0; k < contents.array[i].used; k++) {
+          status = fl_string_dynamic_partial_append_nulless(buffer, contents.array[i].array[k], &values[j]->array[values[j]->used]);
+
+          if (f_status_is_error(status)) return status;
+
+          values[j]->used++;
+        } // for
       } // for
+    } // for
+
+    return status;
+  }
+#endif // _di_fll_fss_snatch_apart_
 
-      if (f_status_is_error(status)) break;
+#ifndef _di_fll_fss_snatch_together_
+  f_return_status fll_fss_snatch_together(const f_string_dynamic buffer, const f_fss_objects objects, const f_fss_contents contents, const f_string names[], const f_string_length lengths[], f_string_dynamic *values[], const f_string_length size) {
+    #ifndef _di_level_2_parameter_checking_
+      if (size == 0) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_2_parameter_checking_
+
+    if (buffer.used == 0) return f_no_data;
+    if (objects.used == 0) return f_no_data;
+    if (contents.used == 0) return f_no_data;
+
+    f_status status = f_none;
+    f_string_length length_object = 0;
+
+    f_array_length i = 0;
+    f_array_length j = 0;
+    f_array_length k = 0;
+
+    for (; i < objects.used; i++) {
+      length_object = (objects.array[i].stop - objects.array[i].start) + 1;
+
+      for (j = 0; j < size; j++) {
+        status = fl_string_compare_trim(buffer.string + objects.array[i].start, names[j], length_object, lengths[j]);
+
+        if (f_status_is_error(status)) return status;
+        if (status == f_not_equal_to) continue;
+
+        for (k = 0; k < contents.array[i].used; k++) {
+          status = fl_string_dynamic_partial_append_nulless(buffer, contents.array[i].array[k], values[j]);
+
+          if (f_status_is_error(status)) return status;
+        } // for
+      } // for
     } // for
 
     return status;
@@ -105,28 +150,27 @@ extern "C" {
       length_object = (objects.array[i].stop - objects.array[i].start) + 1;
 
       for (j = 0; j < size; j++) {
-        if (fl_string_compare_trim(buffer.string + objects.array[i].start, names[j], length_object, lengths[j]) == f_equal_to) {
-          if (values[j]->used == 0) {
-            for (k = 0; k < contents.array[i].used; k++) {
-              status = fl_string_dynamic_partial_mash_nulless(glue, glue_length, buffer, contents.array[i].array[k], values[j]);
+        status = fl_string_compare_trim(buffer.string + objects.array[i].start, names[j], length_object, lengths[j]);
 
-              if (f_status_is_error(status)) break;
-            } // for
+        if (f_status_is_error(status)) return status;
+        if (status == f_not_equal_to) continue;
 
-            if (f_status_is_error(status)) break;
-          }
+        if (values[j]->used == 0) {
+          for (k = 0; k < contents.array[i].used; k++) {
+            status = fl_string_dynamic_partial_mash_nulless(glue, glue_length, buffer, contents.array[i].array[k], values[j]);
+
+            if (f_status_is_error(status)) return status;
+          } // for
         }
       } // for
-
-      if (f_status_is_error(status)) break;
     } // for
 
     return status;
   }
 #endif // _di_fll_fss_snatch_mash_
 
-#ifndef _di_fll_fss_snatch_mash_together_
-  f_return_status fll_fss_snatch_mash_together(const f_string_dynamic buffer, const f_fss_objects objects, const f_fss_contents contents, const f_string names[], const f_string_length lengths[], f_string_dynamic *values[], const f_string_length size, const f_string glue, const f_string_length glue_length) {
+#ifndef _di_fll_fss_snatch_mash_apart_
+  f_return_status fll_fss_snatch_mash_apart(const f_string_dynamic buffer, const f_fss_objects objects, const f_fss_contents contents, const f_string names[], const f_string_length lengths[], f_string_dynamics *values[], const f_string_length size, const f_string glue, const f_string_length glue_length) {
     #ifndef _di_level_2_parameter_checking_
       if (size == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_2_parameter_checking_
@@ -146,18 +190,72 @@ extern "C" {
       length_object = (objects.array[i].stop - objects.array[i].start) + 1;
 
       for (j = 0; j < size; j++) {
-        if (fl_string_compare_trim(buffer.string + objects.array[i].start, names[j], length_object, lengths[j]) == f_equal_to) {
-          for (k = 0; k < contents.array[i].used; k++) {
-            status = fl_string_dynamic_partial_mash_nulless(glue, glue_length, buffer, contents.array[i].array[k], values[j]);
+        status = fl_string_compare_trim(buffer.string + objects.array[i].start, names[j], length_object, lengths[j]);
 
-            if (f_status_is_error(status)) break;
-          } // for
+        if (f_status_is_error(status)) return status;
+        if (status == f_not_equal_to) continue;
+
+        if (values[j]->used + f_fss_default_allocation_step > f_string_max_size) {
+          if (values[j]->used + 1 > f_string_max_size) return f_status_set_error(f_buffer_too_large);
 
-          if (f_status_is_error(status)) break;
+          f_macro_string_dynamics_resize(status, (*values[j]), values[j]->used + 1);
+          if (f_status_is_error(status)) return status;
         }
+        else if (values[j]->used + 1 > values[j]->used) {
+          f_macro_string_dynamics_resize(status, (*values[j]), values[j]->used + f_fss_default_allocation_step);
+          if (f_status_is_error(status)) return status;
+        }
+
+        for (k = 0; k < contents.array[i].used; k++) {
+          status = fl_string_dynamic_partial_mash_nulless(glue, glue_length, buffer, contents.array[i].array[k], &values[j]->array[values[j]->used]);
+
+          if (f_status_is_error(status)) return status;
+        } // for
+
+        if (f_status_is_error(status)) return status;
+
+        values[j]->used++;
       } // for
 
-      if (f_status_is_error(status)) break;
+      if (f_status_is_error(status)) return status;
+    } // for
+
+    return status;
+  }
+#endif // _di_fll_fss_snatch_mash_apart_
+
+#ifndef _di_fll_fss_snatch_mash_together_
+  f_return_status fll_fss_snatch_mash_together(const f_string_dynamic buffer, const f_fss_objects objects, const f_fss_contents contents, const f_string names[], const f_string_length lengths[], f_string_dynamic *values[], const f_string_length size, const f_string glue, const f_string_length glue_length) {
+    #ifndef _di_level_2_parameter_checking_
+      if (size == 0) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_2_parameter_checking_
+
+    if (buffer.used == 0) return f_no_data;
+    if (objects.used == 0) return f_no_data;
+    if (contents.used == 0) return f_no_data;
+
+    f_status status = f_none;
+    f_string_length length_object = 0;
+
+    f_array_length i = 0;
+    f_array_length j = 0;
+    f_array_length k = 0;
+
+    for (; i < objects.used; i++) {
+      length_object = (objects.array[i].stop - objects.array[i].start) + 1;
+
+      for (j = 0; j < size; j++) {
+        status = fl_string_compare_trim(buffer.string + objects.array[i].start, names[j], length_object, lengths[j]);
+
+        if (f_status_is_error(status)) return status;
+        if (status == f_not_equal_to) continue;
+
+        for (k = 0; k < contents.array[i].used; k++) {
+          status = fl_string_dynamic_partial_mash_nulless(glue, glue_length, buffer, contents.array[i].array[k], values[j]);
+
+          if (f_status_is_error(status)) return status;
+        } // for
+      } // for
     } // for
 
     return status;
index 3f9dc7c01c50924a7f2b027b4d2aee34493bb24f..4f44fd33246fde251d3ace19210e82e38faedbed 100644 (file)
@@ -63,6 +63,7 @@ extern "C" {
  *   f_no_data when there is no buffer, objects or contents to process.
  *   f_error_reallocation (with error bit) on reallocation error.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_string_max_size (with error bit) if any combined string is too large when processing values.
  */
 #ifndef _di_fll_fss_snatch_
   extern f_return_status fll_fss_snatch(const f_string_dynamic buffer, const f_fss_objects objects, const f_fss_contents contents, const f_string names[], const f_string_length lengths[], f_string_dynamic *values[], const f_string_length size);
@@ -72,6 +73,45 @@ extern "C" {
  * Perform simple search through all objects against the given set, saving all values when matched.
  *
  * All matches for each name is snatched.
+ * Multiple contents for a single object are stored in separate strings.
+ * Content for multiple identical objects are added in separate strings from other objects.
+ *
+ * This will trim the object names when comparing (removing leading/trailing whitespace).
+ * This will strip NULL charactes when copying.
+ *
+ * This performs only a simple search algorithm that should be acceptable for small sets where performance is generally not a concern.
+ *
+ * @param buffer
+ *   The buffer to read from.
+ * @param objects
+ *   This object mappings to process.
+ * @param contents
+ *   This content mappings to process.
+ * @param names
+ *   An array of strings to "snatch" from the buffer.
+ * @param lengths
+ *   An array of lengths for each names string.
+ * @param values
+ *   An array of values where "snatched" content is stored.
+ * @param size
+ *   The total size of the names, lengths, and values arrays.
+ *
+ * @return
+ *   f_none on success.
+ *   f_no_data when there is no buffer, objects or contents to process.
+ *   f_error_reallocation (with error bit) on reallocation error.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_buffer_too_large (with error bit) on maximum buffer limit reached when processing values.
+ *   f_string_max_size (with error bit) if any combined string is too large when processing values.
+ */
+#ifndef _di_fll_fss_snatch_apart_
+  extern f_return_status fll_fss_snatch_apart(const f_string_dynamic buffer, const f_fss_objects objects, const f_fss_contents contents, const f_string names[], const f_string_length lengths[], f_string_dynamics *values[], const f_string_length size);
+#endif // _di_fll_fss_snatch_apart_
+
+/**
+ * Perform simple search through all objects against the given set, saving all values when matched.
+ *
+ * All matches for each name is snatched.
  * Multiple contents for a single object are appended.
  * Content for multiple identical objects are appended.
  *
@@ -100,6 +140,7 @@ extern "C" {
  *   f_no_data when there is no buffer, objects or contents to process.
  *   f_error_reallocation (with error bit) on reallocation error.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_string_max_size (with error bit) if any combined string is too large when processing values.
  */
 #ifndef _di_fll_fss_snatch_together_
   extern f_return_status fll_fss_snatch_together(const f_string_dynamic buffer, const f_fss_objects objects, const f_fss_contents contents, const f_string names[], const f_string_length lengths[], f_string_dynamic *values[], const f_string_length size);
@@ -142,6 +183,7 @@ extern "C" {
  *   f_no_data when there is no buffer, objects or contents to process.
  *   f_error_reallocation (with error bit) on reallocation error.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_string_max_size (with error bit) if any combined string is too large when processing values.
  */
 #ifndef _di_fll_fss_snatch_mash_
   extern f_return_status fll_fss_snatch_mash(const f_string_dynamic buffer, const f_fss_objects objects, const f_fss_contents contents, const f_string names[], const f_string_length lengths[], f_string_dynamic *values[], const f_string_length size, const f_string glue, const f_string_length glue_length);
@@ -152,6 +194,48 @@ extern "C" {
  *
  * All matches for each name is snatched.
  * Multiple contents for a single object are appended using the provided glue.
+ * Content for multiple identical objects are added in separate strings from other objects.
+ *
+ * This will trim the object names when comparing (removing leading/trailing whitespace).
+ * This will strip NULL charactes when copying.
+ *
+ * This performs only a simple search algorithm that should be acceptable for small sets where performance is generally not a concern.
+ *
+ * @param buffer
+ *   The buffer to read from.
+ * @param objects
+ *   This object mappings to process.
+ * @param contents
+ *   This content mappings to process.
+ * @param names
+ *   An array of strings to "snatch" from the buffer.
+ * @param lengths
+ *   An array of lengths for each names string.
+ * @param values
+ *   An array of values where "snatched" content is stored.
+ * @param size
+ *   The total size of the names, lengths, and values arrays.
+ * @param glue
+ *   A string to append between each duplicate name found when "snatching".
+ * @param glue_length
+ *   The length of the glue string.
+ *
+ * @return
+ *   f_none on success.
+ *   f_no_data when there is no buffer, objects or contents to process.
+ *   f_error_reallocation (with error bit) on reallocation error.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_string_max_size (with error bit) if any combined string is too large when processing values.
+ */
+#ifndef _di_fll_fss_snatch_mash_apart_
+  extern f_return_status fll_fss_snatch_mash_apart(const f_string_dynamic buffer, const f_fss_objects objects, const f_fss_contents contents, const f_string names[], const f_string_length lengths[], f_string_dynamics *values[], const f_string_length size, const f_string glue, const f_string_length glue_length);
+#endif // _di_fll_fss_snatch_mash_apart_
+
+/**
+ * Perform simple search through all objects against the given set, saving all values when matched.
+ *
+ * All matches for each name is snatched.
+ * Multiple contents for a single object are appended using the provided glue.
  * Content for multiple identical objects are appended using the provided glue.
  *
  * This will trim the object names when comparing (removing leading/trailing whitespace).
@@ -183,6 +267,7 @@ extern "C" {
  *   f_no_data when there is no buffer, objects or contents to process.
  *   f_error_reallocation (with error bit) on reallocation error.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_string_max_size (with error bit) if any combined string is too large when processing values.
  */
 #ifndef _di_fll_fss_snatch_mash_together_
   extern f_return_status fll_fss_snatch_mash_together(const f_string_dynamic buffer, const f_fss_objects objects, const f_fss_contents contents, const f_string names[], const f_string_length lengths[], f_string_dynamic *values[], const f_string_length size, const f_string glue, const f_string_length glue_length);