completed documentation on sstr_t + sstrsplit overhaul + allocator version of sstrsplit

Fri, 19 Jul 2013 14:17:12 +0200

author
Mike Becker <universe@uap-core.de>
date
Fri, 19 Jul 2013 14:17:12 +0200
changeset 119
baa839a7633f
parent 118
151f5345f303
child 120
8170f658f017

completed documentation on sstr_t + sstrsplit overhaul + allocator version of sstrsplit

ucx/string.c file | annotate | diff | comparison | revisions
ucx/string.h file | annotate | diff | comparison | revisions
--- a/ucx/string.c	Wed Jul 17 20:03:01 2013 +0200
+++ b/ucx/string.c	Fri Jul 19 14:17:12 2013 +0200
@@ -73,7 +73,7 @@
     memcpy(ptr, c1.ptr, cplen);
     len -= cplen;
     ptr += cplen;
-    for (size_t i = 0 ; i < n-1 ; i++) {
+    for (size_t i = 1 ; i < n ; i++) {
         sstr_t str = va_arg (ap, sstr_t);
         cplen = str.length > len ? len : str.length;
         if(cplen <= 0) {
@@ -120,7 +120,12 @@
 }
 
 sstr_t* sstrsplit(sstr_t s, sstr_t d, size_t *n) {
-    if (d.length == 0) {
+    return sstrsplita(s, d, n, ucx_default_allocator());
+}
+
+sstr_t* sstrsplita(sstr_t s, sstr_t d, size_t *n, UcxAllocator *allocator) {
+    if (s.length == 0 || d.length == 0) {
+        *n = -1;
         return NULL;
     }
 
@@ -129,11 +134,15 @@
     *n = 1;
 
     /* special case: exact match - no processing needed */
-    if (s.length == d.length && strncmp(s.ptr, d.ptr, s.length) == 0) {
+    if (sstrcmp(s, d) == 0) {
         *n = 0;
         return NULL;
     }
     sstr_t sv = sstrdup(s);
+    if (sv.length == 0) {
+        *n = -2;
+        return NULL;
+    }
 
     for (size_t i = 0 ; i < s.length ; i++) {
         if (sv.ptr[i] == d.ptr[0]) {
@@ -156,19 +165,23 @@
         }
         if ((*n) == nmax) break;
     }
-    result = (sstr_t*) malloc(sizeof(sstr_t) * (*n));
+    result = (sstr_t*) allocator->malloc(sizeof(sstr_t) * (*n));
 
-    char *pptr = sv.ptr;
-    for (size_t i = 0 ; i < *n ; i++) {
-        size_t l = strlen(pptr);
-        char* ptr = (char*) malloc(l + 1);
-        memcpy(ptr, pptr, l);
-        ptr[l] = 0;
+    if (result) {
+        char *pptr = sv.ptr;
+        for (size_t i = 0 ; i < *n ; i++) {
+            size_t l = strlen(pptr);
+            char* ptr = (char*) allocator->malloc(l + 1);
+            memcpy(ptr, pptr, l);
+            ptr[l] = 0;
 
-        result[i] = sstrn(ptr, l);
-        pptr += l + d.length;
+            result[i] = sstrn(ptr, l);
+            pptr += l + d.length;
+        }
+    } else {
+        *n = -2;
     }
-
+    
     free(sv.ptr);
 
     return result;
--- a/ucx/string.h	Wed Jul 17 20:03:01 2013 +0200
+++ b/ucx/string.h	Fri Jul 19 14:17:12 2013 +0200
@@ -119,48 +119,157 @@
 size_t sstrnlen(size_t count, sstr_t string, ...);
 
 
-/*
- * concatenates n strings
- *
- * n    number of strings
- * s    new string with enough memory allocated
- * ...  strings
+/**
+ * Concatenates strings.
+ * 
+ * At least one string must be specified and there must be enough memory
+ * available referenced by the destination sstr_t.ptr for this function to
+ * successfully concatenate all specified strings.
+ * 
+ * The sstr_t.length of the destination string specifies the capacity and
+ * should match the total memory available referenced by the destination
+ * sstr_t.ptr. This function <i>never</i> copies data beyond the capacity and
+ * does not modify any of the source strings.
+ * 
+ * <b>Attention:</b>
+ * <ul>
+ *   <li>Any content in the destination string will be overwritten</li>
+ *   <li>The destination sstr_t.ptr is <b>NOT</b>
+ *       <code>NULL</code>-terminated</li>
+ *   <li>The destination sstr_t.length is set to the total length of the
+ *       concatenated strings</li>
+ *   <li><i>Hint:</i> get a <code>NULL</code>-terminated string by performing
+ *       <code>mystring.ptr[mystring.length]='\0'</code> after calling this
+ *       function</li>
+ * </ul>
+  *
+ * @param count   the total number of strings to concatenate
+ * @param dest    new sstr_t with capacity information and allocated memory
+ * @param src     the first string
+ * @param ...     all other strings
+ * @return the argument for <code>dest</code> is returned
  */
-sstr_t sstrncat(size_t n, sstr_t s, sstr_t c1, ...);
+sstr_t sstrncat(size_t count, sstr_t dest, sstr_t src, ...);
 
 
-/*
- *
+/**
+ * Returns a substring starting at the specified location.
+ * 
+ * <b>Attention:</b> the new string references the same memory area as the
+ * input string and will <b>NOT</b> be <code>NULL</code>-terminated.
+ * Use sstrdup() to get a copy.
+ * 
+ * @param string input string
+ * @param start  start location of the substring
+ * @return a substring of <code>string</code> starting at <code>start</code>
+ * 
+ * @see sstrsubsl()
+ * @see sstrchr()
  */
-sstr_t sstrsubs(sstr_t s, size_t start);
+sstr_t sstrsubs(sstr_t string, size_t start);
 
-/*
- *
+/**
+ * Returns a substring with a maximum length starting at the specified location.
+ * 
+ * <b>Attention:</b> the new string references the same memory area as the
+ * input string and will <b>NOT</b> be <code>NULL</code>-terminated.
+ * Use sstrdup() to get a copy.
+ * 
+ * @param string input string
+ * @param start  start location of the substring
+ * @param length the maximum length of the substring
+ * @return a substring of <code>string</code> starting at <code>start</code>
+ * with a maximum length of <code>length</code>
+ * 
+ * @see sstrsubs()
+ * @see sstrchr()
  */
-sstr_t sstrsubsl(sstr_t s, size_t start, size_t length);
+sstr_t sstrsubsl(sstr_t string, size_t start, size_t length);
 
-/*
+/**
+ * Returns a substring starting at the location of the first occurrence of the
+ * specified character.
+ * 
+ * If the string does not contain the character, an empty string is returned.
  * 
+ * @param string the string where to locate the character
+ * @param chr    the character to locate
+ * @return       a substring starting at the least location of <code>chr</code>
+ * 
+ * @see sstrsubs()
  */
-sstr_t sstrchr(sstr_t s, int c);
+sstr_t sstrchr(sstr_t string, int chr);
 
-/*
- * splits s into n parts
- *
- * s    the string to split
- * d    the delimiter string
- * n    the maximum size of the resulting list
- *      a size of 0 indicates an unbounded list size
- *      the actual size of the list will be stored here
+/**
+ * Splits a string into parts by using a delimiter string.
+ * 
+ * This function will return <code>NULL</code>, if one of the following happens:
+ * <ul>
+ *   <li>the string length is zero</li>
+ *   <li>the delimeter length is zero</li>
+ *   <li>the string equals the delimeter</li>
+ *   <li>memory allocation fails</li>
+ * </ul>
+ * 
+ * The integer referenced by <code>count</code> is used as input and determines
+ * the maximum size of the resulting list, i.e. the maximum count of splits to
+ * perform + 1.
+ * 
+ * The integer referenced by <code>count</code> is also used as output and is
+ * set to
+ * <ul>
+ *   <li>-2, on memory allocation errors</li>
+ *   <li>-1, if either the string or the delimiter is an empty string</li>
+ *   <li>0, if the string equals the delimiter</li>
+ *   <li>1, if the string does not contain the delimiter</li>
+ *   <li>the count of list items, otherwise</li>
+ * </ul>
+ * 
+ * If the string starts with the delimiter, the first item of the resulting
+ * list will be an empty string.
+ * 
+ * If the string ends with the delimiter and the maximum list size is not
+ * exceeded, the last list item will be an empty string.
+ * 
+ * <b>Attention:</b> All list items <b>AND</b> all sstr_t.ptr of the list
+ * items must be manually passed to <code>free()</code>. Use sstrsplita() with
+ * an allocator to managed memory, to avoid this.
  *
- *      Hint: use this value to avoid dynamic reallocation of the result list
- *
- * Returns a list of the split strings
- * NOTE: this list needs to be freed manually after usage
- *
- * Returns NULL on error
+ * @param string the string to split
+ * @param delim  the delimiter string
+ * @param count  IN: the maximum size of the resulting list (0 for an
+ *               unbounded list), OUT: the actual size of the list
+ * @return a list of the split strings as sstr_t array or
+ *         <code>NULL</code> on error
+ * 
+ * @see sstrsplita()
  */
-sstr_t* sstrsplit(sstr_t s, sstr_t d, size_t *n);
+sstr_t* sstrsplit(sstr_t string, sstr_t delim, size_t *count);
+
+/**
+ * Performing sstrsplit() using an UcxAllocator.
+ * 
+ * <i>Read the description of sstrsplit() for details.</i>
+ * 
+ * The memory for the sstr_t.ptr pointers of the list items and the memory for
+ * the sstr_t array itself are allocated by using the UcxAllocator.malloc()
+ * function.
+ * 
+ * <b>Note:</b> the allocator is not used for memory that is freed within the
+ * same call of this function (locally scoped variables).
+ * 
+ * @param string the string to split
+ * @param delim  the delimiter string
+ * @param count  IN: the maximum size of the resulting list (0 for an
+ *               unbounded list), OUT: the actual size of the list
+ * @param allocator the UcxAllocator used for allocating memory
+ * @return a list of the split strings as sstr_t array or
+ *         <code>NULL</code> on error
+ * 
+ * @see sstrsplit()
+ */
+sstr_t* sstrsplita(sstr_t string, sstr_t delim, size_t *count,
+        UcxAllocator *allocator);
 
 /**
  * Compares two UCX strings with standard <code>memcmp()</code>.
@@ -188,6 +297,7 @@
  * 
  * @param string the string to duplicate
  * @return a duplicate of the string
+ * @see sstrdupa()
  */
 sstr_t sstrdup(sstr_t string);
 
@@ -205,6 +315,7 @@
  * @param allocator a valid instance of an UcxAllocator
  * @param string the string to duplicate
  * @return a duplicate of the string
+ * @see sstrdup()
  */
 sstr_t sstrdupa(UcxAllocator *allocator, sstr_t string);
 

mercurial