bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: new module 'memxfrm'


From: Bruno Haible
Subject: Re: new module 'memxfrm'
Date: Sat, 7 Mar 2009 14:22:23 +0100
User-agent: KMail/1.9.9

This patch improves the calling convention of memxfrm(), so that it does allows
preallocated buffers, to minimize the overhead of memory allocation.

--- lib/memxfrm.h.orig  2009-03-07 14:19:47.000000000 +0100
+++ lib/memxfrm.h       2009-03-07 14:16:50.000000000 +0100
@@ -33,10 +33,12 @@
    restored before this function returns.
    The result of this function depends on the LC_COLLATE category of the
    current locale.
-   If successful, return the freshly allocated transformed string and set
-   *LENGTHP to its length,
+   If successful: If resultbuf is not NULL and the result fits into *lengthp
+   bytes, it is put in resultbuf, and resultbuf is returned.  Otherwise, a
+   freshly allocated string is returned.  In both cases, *lengthp is set to the
+   length of the returned string.
    Upon failure, return NULL, with errno set.  */
-extern char * memxfrm (char *s, size_t n, size_t *lengthp);
+extern char * memxfrm (char *s, size_t n, char *resultbuf, size_t *lengthp);
 
 
 #ifdef __cplusplus
--- lib/memxfrm.c.orig  2009-03-07 14:19:47.000000000 +0100
+++ lib/memxfrm.c       2009-03-07 14:16:42.000000000 +0100
@@ -25,7 +25,7 @@
 #include <string.h>
 
 char *
-memxfrm (char *s, size_t n, size_t *lengthp)
+memxfrm (char *s, size_t n, char *resultbuf, size_t *lengthp)
 {
   /* Result accumulator.  */
   char *result;
@@ -35,10 +35,18 @@
   char orig_sentinel;
 
   /* Initial memory allocation.  */
-  allocated = (n > 0 ? n : 1);
-  result = (char *) malloc (allocated);
-  if (result == NULL)
-    goto out_of_memory_2;
+  if (resultbuf != NULL && *lengthp > 0)
+    {
+      result = resultbuf;
+      allocated = *lengthp;
+    }
+  else
+    {
+      allocated = (n > 0 ? n : 1);
+      result = (char *) malloc (allocated);
+      if (result == NULL)
+       goto out_of_memory_2;
+    }
   length = 0;
 
   /* Add sentinel.byte.  */
@@ -72,7 +80,12 @@
                char *new_result;
 
                allocated = 2 * allocated;
-               new_result = (char *) realloc (result, allocated);
+               if (allocated < 64)
+                 allocated = 64;
+               if (result == resultbuf)
+                 new_result = (char *) malloc (allocated);
+               else
+                 new_result = (char *) realloc (result, allocated);
                if (new_result == NULL)
                  goto out_of_memory_1;
                result = new_result;
@@ -93,7 +106,7 @@
   }
 
   /* Shrink the allocated memory if possible.  */
-  if ((length > 0 ? length : 1) < allocated)
+  if (result != resultbuf && (length > 0 ? length : 1) < allocated)
     {
       char *memory = (char *) realloc (result, length > 0 ? length : 1);
       if (memory != NULL)
@@ -107,14 +120,16 @@
  fail:
   {
     int saved_errno = errno;
-    free (result);
+    if (result != resultbuf)
+      free (result);
     s[n] = orig_sentinel;
     errno = saved_errno;
     return NULL;
   }
 
  out_of_memory_1:
-  free (result);
+  if (result != resultbuf)
+    free (result);
   s[n] = orig_sentinel;
  out_of_memory_2:
   errno = ENOMEM;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]