From dadaf300eb571bf4585846993b1cf3743399937e Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sun, 10 May 2020 00:45:03 -0500 Subject: [PATCH] Feature: Add string assure functions to assure a given string exists at the beginning or the end This is particularly useful for assuring that a "/" exists and the end of generated path strings. --- level_1/fl_string/c/string.c | 470 ++++++++++++++++++++++++++++++++++++++++++- level_1/fl_string/c/string.h | 321 ++++++++++++++++++++++++++++- level_1/fl_utf/c/utf.c | 470 ++++++++++++++++++++++++++++++++++++++++++- level_1/fl_utf/c/utf.h | 329 +++++++++++++++++++++++++++++- 4 files changed, 1586 insertions(+), 4 deletions(-) diff --git a/level_1/fl_string/c/string.c b/level_1/fl_string/c/string.c index b515eb9..b1b9a21 100644 --- a/level_1/fl_string/c/string.c +++ b/level_1/fl_string/c/string.c @@ -17,6 +17,82 @@ extern "C" { } #endif // _di_fl_string_append_ +#ifndef _di_fl_string_append_assure_ + f_return_status fl_string_append_assure(const f_string source, const f_string_length length, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (length == 0) return f_no_data; + + if (destination->used < length) { + return private_fl_string_append(source, length, destination); + } + + f_string_length i = 1; + f_string_length j = 1; + + while (i <= length && j <= destination->used) { + if (source[length - i] == f_string_eos) { + i++; + continue; + } + + if (destination->string[destination->used - j] == f_string_eos) { + j++; + continue; + } + + if (source[length - i] != destination->string[destination->used - j]) { + return private_fl_string_append(source, length, destination); + } + + i++; + j++; + } // while + + return f_none; + } +#endif // _di_fl_string_append_assure_ + +#ifndef _di_fl_string_append_assure_nulless_ + f_return_status fl_string_append_assure_nulless(const f_string source, const f_string_length length, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (length == 0) return f_no_data; + + if (destination->used < length) { + return private_fl_string_append_nulless(source, length, destination); + } + + f_string_length i = 1; + f_string_length j = 1; + + while (i <= length && j <= destination->used) { + if (source[length - i] == f_string_eos) { + i++; + continue; + } + + if (destination->string[destination->used - j] == f_string_eos) { + j++; + continue; + } + + if (source[length - i] != destination->string[destination->used - j]) { + return private_fl_string_append_nulless(source, length, destination); + } + + i++; + j++; + } // while + + return f_none; + } +#endif // _di_fl_string_append_assure_nulless_ + #ifndef _di_fl_string_append_nulless_ f_return_status fl_string_append_nulless(const f_string source, const f_string_length length, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ @@ -65,6 +141,82 @@ extern "C" { } #endif // _di_fl_string_dynamic_append_ +#ifndef _di_fl_string_dynamic_append_assure_ + f_return_status fl_string_dynamic_append_assure(const f_string_static source, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (source.used == 0) return f_no_data; + + if (destination->used < source.used) { + return private_fl_string_append(source.string, source.used, destination); + } + + f_string_length i = 1; + f_string_length j = 1; + + while (i <= source.used && j <= destination->used) { + if (source.string[source.used - i] == f_string_eos) { + i++; + continue; + } + + if (destination->string[destination->used - j] == f_string_eos) { + j++; + continue; + } + + if (source.string[source.used - i] != destination->string[destination->used - j]) { + return private_fl_string_append(source.string, source.used, destination); + } + + i++; + j++; + } // while + + return f_none; + } +#endif // _di_fl_string_dynamic_append_assure_ + +#ifndef _di_fl_string_dynamic_append_assure_nulless_ + f_return_status fl_string_dynamic_append_assure_nulless(const f_string_static source, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (source.used == 0) return f_no_data; + + if (destination->used < source.used) { + return private_fl_string_append_nulless(source.string, source.used, destination); + } + + f_string_length i = 1; + f_string_length j = 1; + + while (i <= source.used && j <= destination->used) { + if (source.string[source.used - i] == f_string_eos) { + i++; + continue; + } + + if (destination->string[destination->used - j] == f_string_eos) { + j++; + continue; + } + + if (source.string[source.used - i] != destination->string[destination->used - j]) { + return private_fl_string_append_nulless(source.string, source.used, destination); + } + + i++; + j++; + } // while + + return f_none; + } +#endif // _di_fl_string_dynamic_append_assure_nulless_ + #ifndef _di_fl_string_dynamic_append_nulless_ f_return_status fl_string_dynamic_append_nulless(const f_string_static source, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ @@ -163,6 +315,86 @@ extern "C" { } #endif // _di_fl_string_dynamic_partial_append_ +#ifndef _di_fl_string_dynamic_partial_append_assure_ + f_return_status fl_string_dynamic_partial_append_assure(const f_string_static source, const f_string_range range, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (source.used == 0) return f_no_data; + if (range.start > range.stop) return f_no_data; + + f_string_length length = (range.stop - range.start) + 1; + + if (destination->used < length) { + return private_fl_string_append(source.string + range.start, length, destination); + } + + f_string_length i = 1; + f_string_length j = 1; + + while (i <= length && j <= destination->used) { + if (source.string[range.stop - i] == f_string_eos) { + i++; + continue; + } + + if (destination->string[destination->used - j] == f_string_eos) { + j++; + continue; + } + + if (source.string[range.stop - i] != destination->string[destination->used - j]) { + return private_fl_string_append(source.string + range.start, length, destination); + } + + i++; + j++; + } // while + } +#endif // _di_fl_string_dynamic_partial_append_assure_ + +#ifndef _di_fl_string_dynamic_partial_append_assure_nulless_ + f_return_status fl_string_dynamic_partial_append_assure_nulless(const f_string_static source, const f_string_range range, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (source.used == 0) return f_no_data; + if (range.start > range.stop) return f_no_data; + + f_string_length length = (range.stop - range.start) + 1; + + if (destination->used < length) { + return private_fl_string_append_nulless(source.string + range.start, length, destination); + } + + f_string_length i = 1; + f_string_length j = 1; + + while (i <= length && j <= destination->used) { + if (source.string[range.stop - i] == f_string_eos) { + i++; + continue; + } + + if (destination->string[destination->used - j] == f_string_eos) { + j++; + continue; + } + + if (source.string[range.stop - i] != destination->string[destination->used - j]) { + return private_fl_string_append_nulless(source.string + range.start, length, destination); + } + + i++; + j++; + } // while + } +#endif // _di_fl_string_dynamic_append_assure_nulless_ + #ifndef _di_fl_string_dynamic_partial_append_nulless_ f_return_status fl_string_dynamic_partial_append_nulless(const f_string_static source, const f_string_range range, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ @@ -289,10 +521,94 @@ extern "C" { if (source.used == 0) return f_no_data; if (range.start > range.stop) return f_no_data; - return private_fl_string_prepend(source.string + range.start, (range.stop - range.start) + 1, destination); + f_string_length length = (range.stop - range.start) + 1; + + if (destination->used < length) { + return private_fl_string_prepend(source.string + range.start, length, destination); + } + + f_string_length i = 0; + f_string_length j = 0; + + while (i < length && j < destination->used) { + if (source.string[i + range.start] == f_string_eos) { + i++; + continue; + } + + if (destination->string[j] == f_string_eos) { + j++; + continue; + } + + if (source.string[i + range.start] != destination->string[i]) { + return private_fl_string_prepend(source.string + range.start, length, destination); + } + + i++; + j++; + } // while + + return f_none; } #endif // _di_fl_string_dynamic_partial_prepend_ +#ifndef _di_fl_string_dynamic_partial_prepend_assure_ + f_return_status fl_string_dynamic_partial_prepend_assure(const f_string_static source, const f_string_range range, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (source.used == 0) return f_no_data; + if (range.start > range.stop) return f_no_data; + + f_string_length length = (range.stop - range.start) + 1; + + if (destination->used < length) { + return private_fl_string_prepend_nulless(source.string + range.start, length, destination); + } + + f_string_length i = 0; + f_string_length j = 0; + + while (i < length && j < destination->used) { + if (source.string[i + range.start] == f_string_eos) { + i++; + continue; + } + + if (destination->string[j] == f_string_eos) { + j++; + continue; + } + + if (source.string[i + range.start] != destination->string[i]) { + return private_fl_string_prepend_nulless(source.string + range.start, length, destination); + } + + i++; + j++; + } // while + + return f_none; + } +#endif // _di_fl_string_dynamic_partial_prepend_assure_ + +#ifndef _di_fl_string_dynamic_partial_prepend_assure_nulless_ + f_return_status fl_string_dynamic_partial_prepend_assure_nulless(const f_string_static source, const f_string_range range, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (source.used == 0) return f_no_data; + if (range.start > range.stop) return f_no_data; + + return private_fl_string_prepend_nulless(source.string + range.start, (range.stop - range.start) + 1, destination); + } +#endif // _di_fl_string_dynamic_partial_prepend_assure_nulless + #ifndef _di_fl_string_dynamic_partial_prepend_nulless_ f_return_status fl_string_dynamic_partial_prepend_nulless(const f_string_static source, const f_string_range range, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ @@ -319,6 +635,82 @@ extern "C" { } #endif // _di_fl_string_dynamic_prepend_ +#ifndef _di_fl_string_dynamic_prepend_assure_ + f_return_status fl_string_dynamic_prepend_assure(const f_string_static source, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (source.used == 0) return f_no_data; + + if (destination->used < source.used) { + return private_fl_string_prepend(source.string, source.used, destination); + } + + f_string_length i = 0; + f_string_length j = 0; + + while (i < source.used && j < destination->used) { + if (source.string[i] == f_string_eos) { + i++; + continue; + } + + if (destination->string[j] == f_string_eos) { + j++; + continue; + } + + if (source.string[i] != destination->string[i]) { + return private_fl_string_prepend(source.string, source.used, destination); + } + + i++; + j++; + } // while + + return f_none; + } +#endif // _di_fl_string_dynamic_prepend_assure_ + +#ifndef _di_fl_string_dynamic_prepend_assure_nulless_ + f_return_status fl_string_dynamic_prepend_assure_nulless(const f_string_static source, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (source.used == 0) return f_no_data; + + if (destination->used < source.used) { + return private_fl_string_prepend_nulless(source.string, source.used, destination); + } + + f_string_length i = 0; + f_string_length j = 0; + + while (i < source.used && j < destination->used) { + if (source.string[i] == f_string_eos) { + i++; + continue; + } + + if (destination->string[j] == f_string_eos) { + j++; + continue; + } + + if (source.string[i] != destination->string[i]) { + return private_fl_string_prepend_nulless(source.string, source.used, destination); + } + + i++; + j++; + } // while + + return f_none; + } +#endif // _di_fl_string_dynamic_prepend_assure_nulless_ + #ifndef _di_fl_string_dynamic_prepend_nulless_ f_return_status fl_string_dynamic_prepend_nulless(const f_string_static source, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ @@ -766,6 +1158,82 @@ extern "C" { } #endif // _di_fl_string_prepend_nulless_ +#ifndef _di_fl_string_prepend_assure_ + f_return_status fl_string_prepend_assure(const f_string source, const f_string_length length, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (length == 0) return f_no_data; + + if (destination->used < length) { + return private_fl_string_prepend(source, length, destination); + } + + f_string_length i = 0; + f_string_length j = 0; + + while (i < length && j < destination->used) { + if (source[i] == f_string_eos) { + i++; + continue; + } + + if (destination->string[j] == f_string_eos) { + j++; + continue; + } + + if (source[i] != destination->string[i]) { + return private_fl_string_prepend(source, length, destination); + } + + i++; + j++; + } // while + + return f_none; + } +#endif // _di_fl_string_prepend_assure_ + +#ifndef _di_fl_string_prepend_assure_nulless_ + f_return_status fl_string_prepend_assure_nulless(const f_string source, const f_string_length length, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (length == 0) return f_no_data; + + if (destination->used < length) { + return private_fl_string_prepend_nulless(source, length, destination); + } + + f_string_length i = 0; + f_string_length j = 0; + + while (i < length && j < destination->used) { + if (source[i] == f_string_eos) { + i++; + continue; + } + + if (destination->string[j] == f_string_eos) { + j++; + continue; + } + + if (source[i] != destination->string[i]) { + return private_fl_string_prepend_nulless(source, length, destination); + } + + i++; + j++; + } // while + + return f_none; + } +#endif // _di_fl_string_prepend_assure_nulless_ + #ifndef _di_fl_string_rip_ f_return_status fl_string_rip(const f_string source, const f_string_length length, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ diff --git a/level_1/fl_string/c/string.h b/level_1/fl_string/c/string.h index 311935d..2b64c98 100644 --- a/level_1/fl_string/c/string.h +++ b/level_1/fl_string/c/string.h @@ -59,6 +59,59 @@ extern "C" { #endif // _di_fl_string_append_ /** + * Append the source string onto the destination, but only if the string is not already at the end. + * + * This ignores NULL characters when comparing both the source and the destination. + * + * @param source + * The source string to append. + * @param length + * The length of source to append. + * @param destination + * The destination string the source is appended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0 (start > stop). + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_append_assure_nulless() + */ +#ifndef _di_fl_string_append_assure_ + extern f_return_status fl_string_append_assure(const f_string source, const f_string_length length, f_string_dynamic *destination); +#endif // _di_fl_string_append_assure_ + +/** + * Append the source string onto the destination, but only if the string is not already at the end. + * + * This ignores NULL characters when comparing both the source and the destination. + * Skips over NULL characters from source when appending. + * + * @param source + * The source string to append. + * @param length + * The length of source to append. + * @param destination + * The destination string the source is appended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0 (start > stop). + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_append_assure() + */ +#ifndef _di_fl_string_append_assure_nulless_ + extern f_return_status fl_string_append_assure_nulless(const f_string source, const f_string_length length, f_string_dynamic *destination); +#endif // _di_fl_string_append_assure_nulless_ + +/** * Append the source string onto the destination. * * Skips over NULL characters from source when appending. @@ -168,6 +221,52 @@ extern "C" { /** * Append the source string onto the destination. * + * @param source + * The source string to append. + * @param destination + * The destination string the source is appended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_dynamic_append_assure_nulless() + */ +#ifndef _di_fl_string_dynamic_append_assure_ + extern f_return_status fl_string_dynamic_append_assure(const f_string_static source, f_string_dynamic *destination); +#endif // _di_fl_string_dynamic_append_assure_ + +/** + * Append the source string onto the destination. + * + * Skips over NULL characters from source when appending. + * + * @param source + * The source string to append. + * @param destination + * The destination string the source is appended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_dynamic_append_assure() + */ +#ifndef _di_fl_string_dynamic_append_assure_nulless_ + extern f_return_status fl_string_dynamic_append_assure_nulless(const f_string_static source, f_string_dynamic *destination); +#endif // _di_fl_string_dynamic_append_assure_nulless_ + +/** + * Append the source string onto the destination. + * * Skips over NULL characters from source when appending. * * @param source @@ -381,6 +480,60 @@ extern "C" { #endif // _di_fl_string_dynamic_partial_append_ /** + * Append the source string onto the destination, but only if the string is not already at the end and restricted to the given range + * + * This ignores NULL characters when comparing both the source and the destination. + * + * @param source + * The source string to append. + * @param range + * A range within the source to restrict the copy from. + * @param destination + * The destination string the source is appended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0 or range is 0 (start > stop). + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_dynamic_partial_append_assure_nulless() + */ +#ifndef _di_fl_string_dynamic_partial_append_assure_ + extern f_return_status fl_string_dynamic_partial_append_assure(const f_string_static source, const f_string_range range, f_string_dynamic *destination); +#endif // _di_fl_string_dynamic_partial_append_assure_ + +/** + * Append the source string onto the destination, but only if the string is not already at the end and restricted to the given range + * + * This ignores NULL characters when comparing both the source and the destination. + * + * Skips over NULL characters from source when appending. + * + * @param source + * The source string to append. + * @param range + * A range within the source to restrict the copy from. + * @param destination + * The destination string the source is appended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0 or range is 0 (start > stop). + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_dynamic_partial_append_assure() + */ +#ifndef _di_fl_string_dynamic_partial_append_assure_nulless_ + extern f_return_status fl_string_dynamic_partial_append_assure_nulless(const f_string_static source, const f_string_range range, f_string_dynamic *destination); +#endif // _di_fl_string_dynamic_partial_append_assure_nulless_ + +/** * Append the source string onto the destination, but restricted to the given range. * * Skips over NULL characters from source when appending. @@ -616,6 +769,62 @@ extern "C" { #endif // _di_fl_string_dynamic_partial_prepend_ /** + * Prepend the source string onto the destination, but only if the string is not already at the end and restricted to the given range + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * This ignores NULL characters when comparing both the source and the destination. + * + * @param source + * The source string to prepend. + * @param range + * A range within the source to restrict the copy from. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0 or range is 0 (start > stop). + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_dynamic_partial_prepend_assure_nulless() + */ +#ifndef _di_fl_string_dynamic_partial_prepend_assure_ + extern f_return_status fl_string_dynamic_partial_prepend_assure(const f_string_static source, const f_string_range range, f_string_dynamic *destination); +#endif // _di_fl_string_dynamic_partial_prepend_assure_ + +/** + * Prepend the source string onto the destination, but only if the string is not already at the end and restricted to the given range + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * This ignores NULL characters when comparing both the source and the destination. + * + * @param source + * The source string to prepend. + * @param range + * A range within the source to restrict the copy from. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0 or range is 0 (start > stop). + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_dynamic_partial_prepend_assure() + */ +#ifndef _di_fl_string_dynamic_partial_prepend_assure_nulless_ + extern f_return_status fl_string_dynamic_partial_prepend_assure_nulless(const f_string_static source, const f_string_range range, f_string_dynamic *destination); +#endif // _di_fl_string_dynamic_partial_prepend_assure_nulless_ + +/** * Prepend the source string onto the destination, but restricted to the given range. * * Prepend operations require memory move operations and are therefore likely more expensive than append operations. @@ -666,6 +875,58 @@ extern "C" { #endif // _di_fl_string_dynamic_prepend_ /** + * Prepend the source string onto the destination, but only if the string is not already at the beginning. + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * This ignores NULL characters when comparing both the source and the destination. + * + * @param source + * The source string to prepend. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_dynamic_prepend_assure_nulless() + */ +#ifndef _di_fl_string_dynamic_prepend_assure_ + extern f_return_status fl_string_dynamic_prepend_assure(const f_string_static source, f_string_dynamic *destination); +#endif // _di_fl_string_dynamic_prepend_assure_ + +/** + * Prepend the source string onto the destination, but only if the string is not already at the beginning. + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * This ignores NULL characters when comparing both the source and the destination. + * + * @param source + * The source string to prepend. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_dynamic_prepend_assure() + */ +#ifndef _di_fl_string_dynamic_prepend_assure_nulless_ + extern f_return_status fl_string_dynamic_prepend_assure_nulless(const f_string_static source, f_string_dynamic *destination); +#endif // _di_fl_string_dynamic_prepend_assure_nulless_ + +/** * Prepend the source string onto the destination. * * Prepend operations require memory move operations and are therefore likely more expensive than append operations. @@ -1080,10 +1341,68 @@ extern "C" { #endif // _di_fl_string_prepend_ /** - * Prepend the source string onto the destination. + * Prepend the source string onto the destination, but only if the string is not already at the beginning. + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * This ignores NULL characters when comparing both the source and the destination. + * + * @param source + * The source string to prepend. + * @param length + * The length of source to append. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0 (start > stop). + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_prepend_assure_nulless() + */ +#ifndef _di_fl_string_prepend_assure_ + extern f_return_status fl_string_prepend_assure(const f_string source, const f_string_length length, f_string_dynamic *destination); +#endif // _di_fl_string_prepend_assure_ + +/** + * Prepend the source string onto the destination, but only if the string is not already at the beginning. + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * This ignores NULL characters when comparing both the source and the destination. + * Skips over NULL characters from source when prepending. + * + * @param source + * The source string to prepend. + * @param length + * The length of source to append. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0 (start > stop). + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_dynamic_prepend_assure() + */ +#ifndef _di_fl_string_prepend_assure_nulless_ + extern f_return_status fl_string_prepend_assure_nulless(const f_string source, const f_string_length length, f_string_dynamic *destination); +#endif // _di_fl_string_prepend_assure_nulless_ + +/** + * Prepend the source string onto the destination, but only if the string is not already at the beginning. * * Prepend operations require memory move operations and are therefore likely more expensive than append operations. * + * This ignores NULL characters when comparing both the source and the destination. * Skips over NULL characters from source when prepending. * * @param source diff --git a/level_1/fl_utf/c/utf.c b/level_1/fl_utf/c/utf.c index a9140ca..0d82090 100644 --- a/level_1/fl_utf/c/utf.c +++ b/level_1/fl_utf/c/utf.c @@ -29,6 +29,82 @@ extern "C" { } #endif // _di_fl_utf_string_append_nulless_ +#ifndef _di_fl_utf_string_append_assure_ + f_return_status fl_utf_string_append_assure(const f_utf_string source, const f_utf_string_length length, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (length == 0) return f_no_data; + + if (destination->used < length) { + return private_fl_utf_string_append(source, length, destination); + } + + f_utf_string_length i = 1; + f_utf_string_length j = 1; + + while (i <= length && j <= destination->used) { + if (source[length - i] == f_utf_character_eos) { + i++; + continue; + } + + if (destination->string[destination->used - j] == f_utf_character_eos) { + j++; + continue; + } + + if (source[length - i] != destination->string[destination->used - j]) { + return private_fl_utf_string_append(source, length, destination); + } + + i++; + j++; + } // while + + return f_none; + } +#endif // _di_fl_utf_string_append_assure_ + +#ifndef _di_fl_utf_string_append_assure_nulless_ + f_return_status fl_utf_string_append_assure_nulless(const f_utf_string source, const f_utf_string_length length, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (length == 0) return f_no_data; + + if (destination->used < length) { + return private_fl_utf_string_append_nulless(source, length, destination); + } + + f_utf_string_length i = 1; + f_utf_string_length j = 1; + + while (i <= length && j <= destination->used) { + if (source[length - i] == f_utf_character_eos) { + i++; + continue; + } + + if (destination->string[destination->used - j] == f_utf_character_eos) { + j++; + continue; + } + + if (source[length - i] != destination->string[destination->used - j]) { + return private_fl_utf_string_append_nulless(source, length, destination); + } + + i++; + j++; + } // while + + return f_none; + } +#endif // _di_fl_utf_string_append_assure_nulless_ + #ifndef _di_fl_utf_string_compare_ f_return_status fl_utf_string_compare(const f_utf_string string1, const f_utf_string string2, const f_utf_string_length length1, const f_utf_string_length length2) { #ifndef _di_level_1_parameter_checking_ @@ -63,6 +139,82 @@ extern "C" { } #endif // _di_fl_utf_string_dynamic_append_ +#ifndef _di_fl_utf_string_dynamic_append_assure_ + f_return_status fl_utf_string_dynamic_append_assure(const f_utf_string_dynamic source, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (source.used == 0) return f_no_data; + + if (destination->used < source.used) { + return private_fl_utf_string_append(source.string, source.used, destination); + } + + f_utf_string_length i = 1; + f_utf_string_length j = 1; + + while (i <= source.used && j <= destination->used) { + if (source.string[source.used - i] == f_utf_character_eos) { + i++; + continue; + } + + if (destination->string[destination->used - j] == f_utf_character_eos) { + j++; + continue; + } + + if (source.string[source.used - i] != destination->string[destination->used - j]) { + return private_fl_utf_string_append(source.string, source.used, destination); + } + + i++; + j++; + } // while + + return f_none; + } +#endif // _di_fl_utf_string_dynamic_append_assure_ + +#ifndef _di_fl_utf_string_dynamic_append_assure_nulless_ + f_return_status fl_utf_string_dynamic_append_assure_nulless(const f_utf_string_dynamic source, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (source.used == 0) return f_no_data; + + if (destination->used < source.used) { + return private_fl_utf_string_append_nulless(source.string, source.used, destination); + } + + f_utf_string_length i = 1; + f_utf_string_length j = 1; + + while (i <= source.used && j <= destination->used) { + if (source.string[source.used - i] == f_utf_character_eos) { + i++; + continue; + } + + if (destination->string[destination->used - j] == f_utf_character_eos) { + j++; + continue; + } + + if (source.string[source.used - i] != destination->string[destination->used - j]) { + return private_fl_utf_string_append_nulless(source.string, source.used, destination); + } + + i++; + j++; + } // while + + return f_none; + } +#endif // _di_fl_utf_string_dynamic_append_assure_nulless_ + #ifndef _di_fl_utf_string_dynamic_append_nulless_ f_return_status fl_utf_string_dynamic_append_nulless(const f_utf_string_dynamic source, f_utf_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ @@ -181,6 +333,86 @@ extern "C" { } #endif // _di_fl_utf_string_dynamic_partial_append_ +#ifndef _di_fl_utf_string_dynamic_partial_append_assure_ + f_return_status fl_utf_string_dynamic_partial_append_assure(const f_utf_string_dynamic source, const f_utf_string_range range, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (source.used == 0) return f_no_data; + if (range.start > range.stop) return f_no_data; + + f_utf_string_length length = (range.stop - range.start) + 1; + + if (destination->used < length) { + return private_fl_utf_string_append(source.string + range.start, length, destination); + } + + f_utf_string_length i = 1; + f_utf_string_length j = 1; + + while (i <= length && j <= destination->used) { + if (source.string[range.stop - i] == f_utf_character_eos) { + i++; + continue; + } + + if (destination->string[destination->used - j] == f_utf_character_eos) { + j++; + continue; + } + + if (source.string[range.stop - i] != destination->string[destination->used - j]) { + return private_fl_utf_string_append(source.string + range.start, length, destination); + } + + i++; + j++; + } // while + } +#endif // _di_fl_utf_string_dynamic_partial_append_assure_ + +#ifndef _di_fl_utf_string_dynamic_partial_append_assure_nulless_ + f_return_status fl_utf_string_dynamic_partial_append_assure_nulless(const f_utf_string_dynamic source, const f_utf_string_range range, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (source.used == 0) return f_no_data; + if (range.start > range.stop) return f_no_data; + + f_utf_string_length length = (range.stop - range.start) + 1; + + if (destination->used < length) { + return private_fl_utf_string_append_nulless(source.string + range.start, length, destination); + } + + f_utf_string_length i = 1; + f_utf_string_length j = 1; + + while (i <= length && j <= destination->used) { + if (source.string[range.stop - i] == f_utf_character_eos) { + i++; + continue; + } + + if (destination->string[destination->used - j] == f_utf_character_eos) { + j++; + continue; + } + + if (source.string[range.stop - i] != destination->string[destination->used - j]) { + return private_fl_utf_string_append_nulless(source.string + range.start, length, destination); + } + + i++; + j++; + } // while + } +#endif // _di_fl_utf_string_dynamic_partial_append_assure_nulless_ + #ifndef _di_fl_utf_string_dynamic_partial_append_nulless_ f_return_status fl_utf_string_dynamic_partial_append_nulless(const f_utf_string_dynamic source, const f_utf_string_range range, f_utf_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ @@ -319,6 +551,90 @@ extern "C" { } #endif // _di_fl_utf_string_dynamic_partial_prepend_ +#ifndef _di_fl_utf_string_dynamic_partial_prepend_assure_ + f_return_status fl_utf_string_dynamic_partial_prepend_assure(const f_utf_string_dynamic source, const f_utf_string_range range, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (source.used == 0) return f_no_data; + if (range.start > range.stop) return f_no_data; + + f_utf_string_length length = (range.stop - range.start) + 1; + + if (destination->used < length) { + return private_fl_utf_string_prepend(source.string + range.start, length, destination); + } + + f_utf_string_length i = 0; + f_utf_string_length j = 0; + + while (i < length && j < destination->used) { + if (source.string[i + range.start] == f_utf_character_eos) { + i++; + continue; + } + + if (destination->string[j] == f_utf_character_eos) { + j++; + continue; + } + + if (source.string[i + range.start] != destination->string[i]) { + return private_fl_utf_string_prepend(source.string + range.start, length, destination); + } + + i++; + j++; + } // while + + return f_none; + } +#endif // _di_fl_utf_string_dynamic_partial_prepend_assure_ + +#ifndef _di_fl_utf_string_dynamic_partial_prepend_assure_nulless_ + f_return_status fl_utf_string_dynamic_partial_prepend_assure_nulless(const f_utf_string_dynamic source, const f_utf_string_range range, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (source.used == 0) return f_no_data; + if (range.start > range.stop) return f_no_data; + + f_utf_string_length length = (range.stop - range.start) + 1; + + if (destination->used < length) { + return private_fl_utf_string_prepend_nulless(source.string + range.start, length, destination); + } + + f_utf_string_length i = 0; + f_utf_string_length j = 0; + + while (i < length && j < destination->used) { + if (source.string[i + range.start] == f_utf_character_eos) { + i++; + continue; + } + + if (destination->string[j] == f_utf_character_eos) { + j++; + continue; + } + + if (source.string[i + range.start] != destination->string[i]) { + return private_fl_utf_string_prepend_nulless(source.string + range.start, length, destination); + } + + i++; + j++; + } // while + + return f_none; + } +#endif // _di_fl_utf_string_dynamic_partial_prepend_assure_nulless_ + #ifndef _di_fl_utf_string_dynamic_partial_prepend_nulless_ f_return_status fl_utf_string_dynamic_partial_prepend_nulless(const f_utf_string_dynamic source, const f_utf_string_range range, f_utf_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ @@ -345,6 +661,82 @@ extern "C" { } #endif // _di_fl_utf_string_dynamic_prepend_ +#ifndef _di_fl_utf_string_dynamic_prepend_assure_ + f_return_status fl_utf_string_dynamic_prepend_assure(const f_utf_string_dynamic source, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (source.used == 0) return f_no_data; + + if (destination->used < source.used) { + return private_fl_utf_string_prepend(source.string, source.used, destination); + } + + f_utf_string_length i = 0; + f_utf_string_length j = 0; + + while (i < source.used && j < destination->used) { + if (source.string[i] == f_utf_character_eos) { + i++; + continue; + } + + if (destination->string[j] == f_utf_character_eos) { + j++; + continue; + } + + if (source.string[i] != destination->string[i]) { + return private_fl_utf_string_prepend(source.string, source.used, destination); + } + + i++; + j++; + } // while + + return f_none; + } +#endif // _di_fl_utf_string_dynamic_prepend_assure_ + +#ifndef _di_fl_utf_string_dynamic_prepend_assure_nulless_ + f_return_status fl_utf_string_dynamic_prepend_assure_nulless(const f_utf_string_dynamic source, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (source.used == 0) return f_no_data; + + if (destination->used < source.used) { + return private_fl_utf_string_prepend_nulless(source.string, source.used, destination); + } + + f_utf_string_length i = 0; + f_utf_string_length j = 0; + + while (i < source.used && j < destination->used) { + if (source.string[i] == f_utf_character_eos) { + i++; + continue; + } + + if (destination->string[j] == f_utf_character_eos) { + j++; + continue; + } + + if (source.string[i] != destination->string[i]) { + return private_fl_utf_string_prepend_nulless(source.string, source.used, destination); + } + + i++; + j++; + } // while + + return f_none; + } +#endif // _di_fl_utf_string_dynamic_prepend_assure_nulless_ + #ifndef _di_fl_utf_string_dynamic_prepend_nulless_ f_return_status fl_utf_string_dynamic_prepend_nulless(const f_utf_string_dynamic source, f_utf_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ @@ -619,7 +1011,7 @@ extern "C" { if (f_status_is_error(status)) return status; } - destination->string[destination->used] = f_string_eos; + destination->string[destination->used] = f_utf_character_eos; destination->used = total; return f_none; @@ -718,6 +1110,82 @@ extern "C" { } #endif // _di_fl_utf_string_prepend_ +#ifndef _di_fl_utf_string_prepend_assure_ + f_return_status fl_utf_string_prepend_assure(const f_utf_string source, const f_utf_string_length length, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (length == 0) return f_no_data; + + if (destination->used < length) { + return private_fl_utf_string_prepend(source, length, destination); + } + + f_utf_string_length i = 0; + f_utf_string_length j = 0; + + while (i < length && j < destination->used) { + if (source[i] == f_utf_character_eos) { + i++; + continue; + } + + if (destination->string[j] == f_utf_character_eos) { + j++; + continue; + } + + if (source[i] != destination->string[i]) { + return private_fl_utf_string_prepend(source, length, destination); + } + + i++; + j++; + } // while + + return f_none; + } +#endif // _di_fl_utf_string_prepend_assure_ + +#ifndef _di_fl_utf_string_prepend_assure_nulless_ + f_return_status fl_utf_string_prepend_assure_nulless(const f_utf_string source, const f_utf_string_length length, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (length == 0) return f_no_data; + + if (destination->used < length) { + return private_fl_utf_string_prepend_nulless(source, length, destination); + } + + f_utf_string_length i = 0; + f_utf_string_length j = 0; + + while (i < length && j < destination->used) { + if (source[i] == f_utf_character_eos) { + i++; + continue; + } + + if (destination->string[j] == f_utf_character_eos) { + j++; + continue; + } + + if (source[i] != destination->string[i]) { + return private_fl_utf_string_prepend_nulless(source, length, destination); + } + + i++; + j++; + } // while + + return f_none; + } +#endif // _di_fl_utf_string_prepend_assure_nulless_ + #ifndef _di_fl_utf_string_prepend_nulless_ f_return_status fl_utf_string_prepend_nulless(const f_utf_string source, const f_utf_string_length length, f_utf_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ diff --git a/level_1/fl_utf/c/utf.h b/level_1/fl_utf/c/utf.h index 3b14cd2..de840ad 100644 --- a/level_1/fl_utf/c/utf.h +++ b/level_1/fl_utf/c/utf.h @@ -82,13 +82,70 @@ extern "C" { * f_error_allocation (with error bit) on memory allocation error. * f_error_reallocation (with error bit) on memory reallocation error. * - * @see fl_utf_string_append() + * @see fl_utf_string_append_assure() */ #ifndef _di_fl_utf_string_append_nulless_ extern f_return_status fl_utf_string_append_nulless(const f_utf_string source, const f_utf_string_length length, f_utf_string_dynamic *destination); #endif // _di_fl_utf_string_append_nulless_ /** + * Append the source UTF-8 string onto the destination, but only if the string is not already at the end. + * + * This ignores NULL characters when comparing both the source and the destination. + * + * @param source + * The source string to append. + * @param start + * Inclusive start point of string to append. + * @param stop + * Inclusive stop point of string to append. + * @param destination + * The destination string the source is appended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0 (start > stop). + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_append_assure_nulless() + */ +#ifndef _di_fl_utf_string_append_assure_ + extern f_return_status fl_utf_string_append_assure(const f_utf_string source, const f_utf_string_length length, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_append_assure_ + +/** + * Append the source UTF-8 string onto the destination, but only if the string is not already at the end. + * + * This ignores NULL characters when comparing both the source and the destination. + * Skips over NULL characters from source when appending. + * + * @param source + * The source string to append. + * @param start + * Inclusive start point of string to append. + * @param stop + * Inclusive stop point of string to append. + * @param destination + * The destination string the source is appended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0 (start > stop). + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_append() + */ +#ifndef _di_fl_utf_string_append_assure_nulless_ + extern f_return_status fl_utf_string_append_assure_nulless(const f_utf_string source, const f_utf_string_length length, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_append_assure_nulless_ + +/** * Compare two UTF-8 strings, similar to strncmp(). * * This does not stop on NULL. @@ -172,6 +229,55 @@ extern "C" { #endif // _di_fl_utf_string_dynamic_append_ /** + * Append the source UTF-8 string onto the destination, but only if the string is not already at the end. + * + * This ignores NULL characters when comparing both the source and the destination. + * + * @param source + * The source string to append. + * @param destination + * The destination string the source is appended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_dynamic_append_assure_nulless() + */ +#ifndef _di_fl_utf_string_dynamic_append_assure_ + extern f_return_status fl_utf_string_dynamic_append_assure(const f_utf_string_dynamic source, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_dynamic_append_assure_ + +/** + * Append the source UTF-8 string onto the destination, but only if the string is not already at the end. + * + * This ignores NULL characters when comparing both the source and the destination. + * Skips over NULL characters from source when appending. + * + * @param source + * The source string to append. + * @param destination + * The destination string the source is appended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_dynamic_append_assure() + */ +#ifndef _di_fl_utf_string_dynamic_append_assure_nulless_ + extern f_return_status fl_utf_string_dynamic_append_assure_nulless(const f_utf_string_dynamic source, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_dynamic_append_assure_nulless_ + +/** * Append the source UTF-8 string onto the destination. * * Skips over NULL characters from source when appending. @@ -395,6 +501,58 @@ extern "C" { /** * Append the source UTF-8 string onto the destination, but restricted to the given range. * + * @param source + * The source string to append. + * @param range + * A range within the source to restrict the copy from. + * @param destination + * The destination string the source is appended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0 or range is 0 (start > stop). + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_dynamic_partial_append_assure_nulless() + */ +#ifndef _di_fl_utf_string_dynamic_partial_append_assure_ + extern f_return_status fl_utf_string_dynamic_partial_append_assure(const f_utf_string_dynamic source, const f_utf_string_range range, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_dynamic_partial_append_assure_ + +/** + * Append the source UTF-8 string onto the destination, but only if the string is not already at the end and restricted to the given range + * + * This ignores NULL characters when comparing both the source and the destination. + * Skips over NULL characters from source when appending. + * + * @param source + * The source string to append. + * @param range + * A range within the source to restrict the copy from. + * @param destination + * The destination string the source is appended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0 or range is 0 (start > stop). + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_dynamic_partial_append_assure() + */ +#ifndef _di_fl_utf_string_dynamic_partial_append_assure_nulless_ + extern f_return_status fl_utf_string_dynamic_partial_append_assure_nulless(const f_utf_string_dynamic source, const f_utf_string_range range, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_dynamic_partial_append_assure_nulless_ + +/** + * Append the source UTF-8 string onto the destination, but only if the string is not already at the end and restricted to the given range + * + * This ignores NULL characters when comparing both the source and the destination. * Skips over NULL characters from source when appending. * * @param source @@ -630,6 +788,62 @@ extern "C" { #endif // _di_fl_utf_string_dynamic_partial_prepend_ /** + * Prepend the source string onto the destination, but restricted to the given range, but only if the string is not already at the beginning. + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * This ignores NULL characters when comparing both the source and the destination. + * + * @param source + * The source string to prepend. + * @param range + * A range within the source to restrict the copy from. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0 or range is 0 (start > stop). + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_dynamic_partial_prepend_assure_nulless() + */ +#ifndef _di_fl_utf_string_dynamic_partial_prepend_assure_ + extern f_return_status fl_utf_string_dynamic_partial_prepend_assure(const f_utf_string_dynamic source, const f_utf_string_range range, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_dynamic_partial_prepend_assure_ + +/** + * Prepend the source string onto the destination, but restricted to the given range, but only if the string is not already at the beginning. + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * This ignores NULL characters when comparing both the source and the destination. + * + * @param source + * The source string to prepend. + * @param range + * A range within the source to restrict the copy from. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0 or range is 0 (start > stop). + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_dynamic_partial_prepend_assure() + */ +#ifndef _di_fl_utf_string_dynamic_partial_prepend_assure_nulless_ + extern f_return_status fl_utf_string_dynamic_partial_prepend_assure_nulless(const f_utf_string_dynamic source, const f_utf_string_range range, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_dynamic_partial_prepend_assure_nulless_ + +/** * Prepend the source string onto the destination, but restricted to the given range. * * Prepend operations require memory move operations and are therefore likely more expensive than append operations. @@ -680,6 +894,58 @@ extern "C" { #endif // _di_fl_utf_string_dynamic_prepend_ /** + * Prepend the source string onto the destination, but only if the string is not already at the beginning. + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * This ignores NULL characters when comparing both the source and the destination. + * + * @param source + * The source string to prepend. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_dynamic_prepend_assure_nulless() + */ +#ifndef _di_fl_utf_string_dynamic_prepend_assure_ + extern f_return_status fl_utf_string_dynamic_prepend_assure(const f_utf_string_dynamic source, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_dynamic_prepend_assure_ + +/** + * Prepend the source string onto the destination, but only if the string is not already at the beginning. + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * This ignores NULL characters when comparing both the source and the destination. + * + * @param source + * The source string to prepend. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_dynamic_prepend_assure() + */ +#ifndef _di_fl_utf_string_dynamic_prepend_assure_nulless_ + extern f_return_status fl_utf_string_dynamic_prepend_assure_nulless(const f_utf_string_dynamic source, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_dynamic_prepend_assure_nulless_ + +/** * Prepend the source string onto the destination. * * Prepend operations require memory move operations and are therefore likely more expensive than append operations. @@ -1118,6 +1384,67 @@ extern "C" { #endif // _di_fl_utf_string_prepend_ /** + * Prepend the UTF-8 source string onto the destination, but only if the string is not already at the beginning. + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * This ignores NULL characters when comparing both the source and the destination. + * + * @param source + * The source string to prepend. + * @param start + * Inclusive start point of string to prepend. + * @param stop + * Inclusive stop point of string to prepend. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0 (start > stop). + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_prepend_assure_nulless() + */ +#ifndef _di_fl_utf_string_prepend_assure_ + extern f_return_status fl_utf_string_prepend_assure(const f_utf_string source, const f_utf_string_length length, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_prepend_assure_ + +/** + * Prepend the UTF-8 source string onto the destination, but only if the string is not already at the beginning. + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * This ignores NULL characters when comparing both the source and the destination. + * Skips over NULL characters from source when prepending. + * + * @param source + * The source string to prepend. + * @param start + * Inclusive start point of string to prepend. + * @param stop + * Inclusive stop point of string to prepend. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * f_none on success. + * f_no_data if source length is 0 (start > stop). + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_prepend_assure() + */ +#ifndef _di_fl_utf_string_prepend_assure_nulless_ + extern f_return_status fl_utf_string_prepend_assure_nulless(const f_utf_string source, const f_utf_string_length length, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_prepend_assure_nulless_ + +/** * Prepend the UTF-8 source string onto the destination. * * Prepend operations require memory move operations and are therefore likely more expensive than append operations. -- 1.8.3.1