]> Kevux Git Server - fll/commitdiff
Feature: implement append and prepend string functions
authorKevin Day <thekevinday@gmail.com>
Wed, 29 Apr 2020 02:57:19 +0000 (21:57 -0500)
committerKevin Day <thekevinday@gmail.com>
Wed, 29 Apr 2020 02:57:19 +0000 (21:57 -0500)
level_1/fl_string/c/private-string.c
level_1/fl_string/c/private-string.h
level_1/fl_string/c/string.c
level_1/fl_string/c/string.h

index ee01f3f88748f83b51507679142fcef831295c46..81cdfbe83f575f4fe1d6f372a9be7dd10aae1a13 100644 (file)
@@ -5,6 +5,27 @@
 extern "C" {
 #endif
 
+#if !defined(_di_fl_string_append_) || !defined(_di_fl_string_dynamic_append_) || !defined(_di_fl_string_dynamic_partial_append_)
+  f_return_status private_fl_string_append(const f_string source, const f_string_length source_length, f_string_dynamic *destination) {
+    f_status status = f_none;
+
+    f_string_length total = destination->used + source_length;
+
+    if (total > f_string_max_size) return f_status_set_error(f_string_too_large);
+
+    if (total > destination->size) {
+      f_macro_string_dynamic_resize(status, (*destination), total);
+      if (f_status_is_error(status)) return status;
+    }
+
+    memcpy(destination->string + destination->used, source, source_length);
+
+    destination->used = total;
+
+    return f_none;
+  }
+#endif // !defined(_di_fl_string_append_) || !defined(_di_fl_string_dynamic_append_) || !defined(_di_fl_string_dynamic_partial_append_)
+
 #if !defined(_di_fl_string_compare_) || !defined(_di_fl_string_dynamic_compare_) || !defined(_di_fl_string_dynamic_partial_compare_)
   f_return_status private_fl_string_compare(const f_string string1, const f_string string2, const f_string_length offset1, const f_string_length offset2, const f_string_length stop1, const f_string_length stop2) {
     f_string_length i1 = offset1;
@@ -207,6 +228,33 @@ extern "C" {
   }
 #endif // !defined(_di_fl_string_mash_) || !defined(_di_fl_string_dynamic_mash_) || !defined(_di_fl_string_dynamic_partial_mash_)
 
+#if !defined(_di_fl_string_prepend_) || !defined(_di_fl_string_dynamic_prepend_) || !defined(_di_fl_string_dynamic_partial_prepend_)
+  f_return_status private_fl_string_prepend(const f_string source, const f_string_length source_length, f_string_dynamic *destination) {
+    f_status status = f_none;
+
+    f_string_length total = destination->used + source_length;
+
+    if (total > f_string_max_size) return f_status_set_error(f_string_too_large);
+
+    if (total > destination->size) {
+      f_macro_string_dynamic_resize(status, (*destination), total);
+      if (f_status_is_error(status)) return status;
+    }
+
+    if (destination->used > 0) {
+      memmove(destination->string + source_length, destination->string, destination->used);
+      memcpy(destination->string, source, source_length);
+    }
+    else {
+      memcpy(destination->string, source, source_length);
+    }
+
+    destination->used = total;
+
+    return f_none;
+  }
+#endif // !defined(_di_fl_string_prepend_) || !defined(_di_fl_string_dynamic_prepend_) || !defined(_di_fl_string_dynamic_partial_prepend_)
+
 #if !defined(_di_fl_string_rip_) || !defined(_di_fl_string_dynamic_rip_)
   f_return_status private_fl_string_rip(const f_string string, const f_string_length start, const f_string_length stop, f_string_dynamic *result) {
     // The start and stop point are inclusive locations, and therefore start - stop is actually 1 too few locations.
index 6c339fe340a781bf80ac490b356be0864e56dd49..e5ce484cd0dfa7e93a5fa4209dd3509536ea7879 100644 (file)
@@ -18,6 +18,33 @@ extern "C" {
 #endif
 
 /**
+ * Private implementation of fl_string_append().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param source
+ *   The source string to append.
+ * @param source_length
+ *   Total number of bytes to copy from source string.
+ * @param destination
+ *   The destination string the source and glue are appended onto.
+ *
+ * @return
+ *   f_none on success.
+ *   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()
+ * @see fl_string_dynamic_append()
+ * @see fl_string_dynamic_partial_append()
+ */
+#if !defined(_di_fl_string_append_) || !defined(_di_fl_string_dynamic_append_) || !defined(_di_fl_string_dynamic_partial_append_)
+  extern f_return_status private_fl_string_append(const f_string source, const f_string_length source_length, f_string_dynamic *destination) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_fl_string_append_) || !defined(_di_fl_string_dynamic_append_) || !defined(_di_fl_string_dynamic_partial_append_)
+
+/**
  * Private implementation of fl_string_compare().
  *
  * Intended to be shared to each of the different implementation variations.
@@ -111,6 +138,33 @@ extern "C" {
 #endif // !defined(_di_fl_string_mash_) || !defined(_di_fl_string_dynamic_mash_) || !defined(_di_fl_string_dynamic_partial_mash_)
 
 /**
+ * Private implementation of fl_string_prepend().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param source
+ *   The source string to prepend.
+ * @param source_length
+ *   Total number of bytes to copy from source string.
+ * @param destination
+ *   The destination string the source and glue are prepended onto.
+ *
+ * @return
+ *   f_none on success.
+ *   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()
+ * @see fl_string_dynamic_prepend()
+ * @see fl_string_dynamic_partial_prepend()
+ */
+#if !defined(_di_fl_string_prepend_) || !defined(_di_fl_string_dynamic_prepend_) || !defined(_di_fl_string_dynamic_partial_prepend_)
+  extern f_return_status private_fl_string_prepend(const f_string source, const f_string_length source_length, f_string_dynamic *destination) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_fl_string_prepend_) || !defined(_di_fl_string_dynamic_prepend_) || !defined(_di_fl_string_dynamic_partial_prepend_)
+
+/**
  * Private implementation of fl_string_rip().
  *
  * Intended to be shared to each of the different implementation variations.
index 4b3c1c0b4883828bb2d8d53ae309b1bbb2350f8b..ad606f10ba890879a12bb88ad6ef52990afc3f94 100644 (file)
@@ -5,6 +5,17 @@
 extern "C" {
 #endif
 
+#ifndef _di_fl_string_append_
+  f_return_status fl_string_append(const f_string source, const f_string_length source_length, f_string_dynamic *destination) {
+    #ifndef _di_level_1_parameter_checking_
+      if (source_length < 1) 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_
+
+    return private_fl_string_append(source, source_length, destination);
+  }
+#endif // _di_fl_string_append_
+
 #ifndef _di_fl_string_compare_
   f_return_status fl_string_compare(const f_string string1, const f_string string2, const f_string_length length1, const f_string_length length2) {
     #ifndef _di_level_1_parameter_checking_
@@ -49,6 +60,17 @@ extern "C" {
   }
 #endif // _di_fl_string_dynamic_compare_trim_
 
+#ifndef _di_fl_string_dynamic_append_
+  f_return_status fl_string_dynamic_append(const f_string_dynamic source, f_string_dynamic *destination) {
+    #ifndef _di_level_1_parameter_checking_
+      if (source.used < 1) 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_
+
+    return private_fl_string_append(source.string, source.used, destination);
+  }
+#endif // _di_fl_string_dynamic_append_
+
 #ifndef _di_fl_string_dynamic_mash_
   f_return_status fl_string_dynamic_mash(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
@@ -95,6 +117,20 @@ extern "C" {
   }
 #endif // _di_fl_string_dynamic_partial_compare_trim_
 
+#ifndef _di_fl_string_dynamic_partial_append_
+  f_return_status fl_string_dynamic_partial_append(const f_string_dynamic source, const f_string_location offset, f_string_dynamic *destination) {
+    #ifndef _di_level_1_parameter_checking_
+      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
+      if (destination == 0) return f_status_set_error(f_invalid_parameter);
+
+      if (offset.start > offset.stop) return f_status_set_error(f_invalid_parameter);
+      if (source.used <= offset.stop) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    return private_fl_string_append(source.string + offset.start, (offset.stop - offset.start) + 1, destination);
+  }
+#endif // _di_fl_string_dynamic_partial_append_
+
 #ifndef _di_fl_string_dynamic_partial_mash_
   f_return_status fl_string_dynamic_partial_mash(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, const f_string_location offset, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
@@ -110,6 +146,31 @@ extern "C" {
   }
 #endif // _di_fl_string_dynamic_partial_mash_
 
+#ifndef _di_fl_string_dynamic_partial_prepend_
+  f_return_status fl_string_dynamic_partial_prepend(const f_string_dynamic source, const f_string_location offset, f_string_dynamic *destination) {
+    #ifndef _di_level_1_parameter_checking_
+      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
+      if (destination == 0) return f_status_set_error(f_invalid_parameter);
+
+      if (offset.start > offset.stop) return f_status_set_error(f_invalid_parameter);
+      if (source.used <= offset.stop) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    return private_fl_string_prepend(source.string + offset.start, (offset.stop - offset.start) + 1, destination);
+  }
+#endif // _di_fl_string_dynamic_partial_prepend_
+
+#ifndef _di_fl_string_dynamic_prepend_
+  f_return_status fl_string_dynamic_prepend(const f_string_dynamic source, f_string_dynamic *destination) {
+    #ifndef _di_level_1_parameter_checking_
+      if (source.used < 1) 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_
+
+    return private_fl_string_prepend(source.string, source.used, destination);
+  }
+#endif // _di_fl_string_dynamic_prepend_
+
 #ifndef _di_fl_string_dynamic_rip_
   f_return_status fl_string_dynamic_rip(const f_string_dynamic buffer, const f_string_location location, f_string_dynamic *result) {
     #ifndef _di_level_1_parameter_checking_
@@ -452,6 +513,17 @@ extern "C" {
   }
 #endif // _di_fl_string_mash_
 
+#ifndef _di_fl_string_prepend_
+  f_return_status fl_string_prepend(const f_string source, const f_string_length source_length, f_string_dynamic *destination) {
+    #ifndef _di_level_1_parameter_checking_
+      if (source_length < 1) 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_
+
+    return private_fl_string_prepend(source, source_length, destination);
+  }
+#endif // _di_fl_string_prepend_
+
 #ifndef _di_fl_string_rip_
   f_return_status fl_string_rip(const f_string string, const f_string_length start, const f_string_length stop, f_string_dynamic *result) {
     #ifndef _di_level_1_parameter_checking_
index 1a1bf94408b69eb4f46918f610013a03f00d8c6e..58f078a1ba6bcd452ff2fcda92ebfbf399a0196d 100644 (file)
@@ -35,6 +35,31 @@ extern "C" {
 #endif
 
 /**
+ * Append the source string onto the destination.
+ *
+ * @param source
+ *   The source string to append.
+ * @param source_length
+ *   Total number of bytes to copy from source string.
+ * @param destination
+ *   The destination string the source is appended onto.
+ *
+ * @return
+ *   f_none on success.
+ *   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()
+ * @see fl_string_dynamic_append()
+ * @see fl_string_dynamic_partial_append()
+ */
+#ifndef _di_fl_string_append_
+  extern f_return_status fl_string_append(const f_string source, const f_string_length source_length, f_string_dynamic *destination);
+#endif // _di_fl_string_append_
+
+/**
  * Compare two strings, similar to strncmp().
  *
  * This does not stop on NULL.
@@ -94,6 +119,29 @@ extern "C" {
 #endif // _di_fl_string_compare_trim_
 
 /**
+ * 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_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()
+ * @see fl_string_dynamic_append()
+ * @see fl_string_dynamic_partial_append()
+ */
+#ifndef _di_fl_string_dynamic_append_
+  extern f_return_status fl_string_dynamic_append(const f_string_dynamic source, f_string_dynamic *destination);
+#endif // _di_fl_string_dynamic_append_
+
+/**
  * Compare two strings, similar to strncmp().
  *
  * This does not stop on NULL.
@@ -233,6 +281,31 @@ extern "C" {
 #endif // _di_fl_string_dynamic_partial_compare_trim_
 
 /**
+ * Append the source string onto the destination.
+ *
+ * @param source
+ *   The source string to append.
+ * @param offset
+ *   A range within the source to restrict the append from.
+ * @param destination
+ *   The destination string the source is appended onto.
+ *
+ * @return
+ *   f_none on success.
+ *   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()
+ * @see fl_string_dynamic_append()
+ * @see fl_string_dynamic_partial_append()
+ */
+#ifndef _di_fl_string_dynamic_partial_append_
+  extern f_return_status fl_string_dynamic_partial_append(const f_string_dynamic source, const f_string_location offset, f_string_dynamic *destination);
+#endif // _di_fl_string_dynamic_partial_append_
+
+/**
  * Append the source string onto the destination with the glue in between.
  *
  * If the destination string is empty, then no glue is appended.
@@ -264,6 +337,62 @@ extern "C" {
 #endif // _di_fl_string_dynamic_partial_mash_
 
 /**
+ * Prepend the source string onto the destination.
+ *
+ * Prepend operations require memory move operations and are therefore likely more expensive than append operations.
+ *
+ * @param source
+ *   The source string to prepend.
+ * @param offset
+ *   A range within the source to restrict the prepend from.
+ * @param destination
+ *   The destination string the source is prepended onto.
+ *
+ * @return
+ *   f_none on success.
+ *   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()
+ * @see fl_string_prepend()
+ * @see fl_string_dynamic_append()
+ * @see fl_string_dynamic_prepend()
+ * @see fl_string_dynamic_partial_append()
+ */
+#ifndef _di_fl_string_dynamic_partial_append_
+  extern f_return_status fl_string_dynamic_partial_prepend(const f_string_dynamic source, const f_string_location offset, f_string_dynamic *destination);
+#endif // _di_fl_string_dynamic_partial_append_
+
+/**
+ * Prepend the source string onto the destination.
+ *
+ * Prepend operations require memory move operations and are therefore likely more expensive than append operations.
+ *
+ * @param source
+ *   The source string to prepend.
+ * @param destination
+ *   The destination string the source is prepended onto.
+ *
+ * @return
+ *   f_none on success.
+ *   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()
+ * @see fl_string_prepend()
+ * @see fl_string_dynamic_append()
+ * @see fl_string_dynamic_partial_append()
+ * @see fl_string_dynamic_partial_prepend()
+ */
+#ifndef _di_fl_string_dynamic_prepend_
+  extern f_return_status fl_string_dynamic_prepend(const f_string_dynamic source, f_string_dynamic *destination);
+#endif // _di_fl_string_dynamic_prepend_
+
+/**
  * Allocate a new string from the provided range in the buffer.
  *
  * @param buffer
@@ -513,6 +642,35 @@ extern "C" {
 #endif // _di_fl_string_mash_
 
 /**
+ * Prepend the source string onto the destination.
+ *
+ * Prepend operations require memory move operations and are therefore likely more expensive than append operations.
+ *
+ * @param source
+ *   The source string to prepend.
+ * @param source_length
+ *   Total number of bytes to copy from source string.
+ * @param destination
+ *   The destination string the source is prepended onto.
+ *
+ * @return
+ *   f_none on success.
+ *   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()
+ * @see fl_string_dynamic_append()
+ * @see fl_string_dynamic_prepend()
+ * @see fl_string_dynamic_partial_append()
+ * @see fl_string_dynamic_partial_prepend()
+ */
+#ifndef _di_fl_string_prepend_
+  extern f_return_status fl_string_prepend(const f_string source, const f_string_length source_length, f_string_dynamic *destination);
+#endif // _di_fl_string_prepend_
+
+/**
  * Allocate a new string from the provided range in the string.
  *
  * @param string