From 000c1e83715ac21eb080de7c79059114994bf5d5 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Fri, 8 May 2020 23:28:31 -0500 Subject: [PATCH] Update: add snatch apart functions and improve logic of fss snatch functions 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 | 174 +++++++++++++++++++++++++++++++++++++----------- level_2/fll_fss/c/fss.h | 85 +++++++++++++++++++++++ 2 files changed, 221 insertions(+), 38 deletions(-) diff --git a/level_2/fll_fss/c/fss.c b/level_2/fll_fss/c/fss.c index 5500470..12f4a58 100644 --- a/level_2/fll_fss/c/fss.c +++ b/level_2/fll_fss/c/fss.c @@ -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; diff --git a/level_2/fll_fss/c/fss.h b/level_2/fll_fss/c/fss.h index 3f9dc7c..4f44fd3 100644 --- a/level_2/fll_fss/c/fss.h +++ b/level_2/fll_fss/c/fss.h @@ -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); -- 1.8.3.1