[Top][All Lists]
[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;