summaryrefslogtreecommitdiff
path: root/src/gallery-utils.c
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2009-10-18 13:00:10 +0200
committerTomas Bzatek <tbzatek@users.sourceforge.net>2009-10-18 13:00:10 +0200
commit57f9ecb71cb043a315fa2d6a5f252cadf57c3980 (patch)
tree45325d7b724ac627b22e9d27c5e09760f3717ece /src/gallery-utils.c
parent2f80eb8f35fe77a758037bbaf3b8691af88b36e1 (diff)
downloadcataract-57f9ecb71cb043a315fa2d6a5f252cadf57c3980.tar.xz
Dynamic memory allocation for string replace functions
This will fix all outstanding multithreading issues, coming from statically allocated memory, common for all threads. The algorithms have been further extended to allow input of any size.
Diffstat (limited to 'src/gallery-utils.c')
-rw-r--r--src/gallery-utils.c53
1 files changed, 39 insertions, 14 deletions
diff --git a/src/gallery-utils.c b/src/gallery-utils.c
index 0c24886..0f6ab71 100644
--- a/src/gallery-utils.c
+++ b/src/gallery-utils.c
@@ -28,6 +28,9 @@
#include "gallery-utils.h"
+
+#define STRING_ALLOC_SIZE 4096
+
/*
* str_replace: replace substring 'search' with a 'replace' string
* - multiple occurrences of the string are replaced
@@ -36,31 +39,41 @@
void
str_replace (gchar **dst, const gchar *search, const gchar *replace)
{
- #define REPLACE_MAX_LENGTH 32768
- static gchar d[REPLACE_MAX_LENGTH];
+ gchar *d;
gchar *src;
gchar *found;
int i;
+ int alloc_size;
+ int used;
- /* TODO: add range checking */
- if (strstr (*dst, search) == NULL || strlen (*dst) == 0 || strlen (search) == 0)
+ if (! dst || ! search || strlen (*dst) == 0 || strlen (search) == 0 || strstr (*dst, search) == NULL)
return;
+ /* let's suppose just one occurrence of replace, realloc if needed */
+ used = strlen (*dst) + 1;
+ alloc_size = (((used + strlen (replace)) / STRING_ALLOC_SIZE) + 1) * STRING_ALLOC_SIZE;
+ d = g_malloc (alloc_size);
+
i = 0;
src = *dst;
while (strstr (src, search)) {
found = strstr (src, search);
+ used += strlen (replace) - strlen (search);
+ if (used > alloc_size) {
+ alloc_size = ((used / STRING_ALLOC_SIZE) + 1) * STRING_ALLOC_SIZE;
+ d = g_realloc (d, alloc_size);
+ }
/* copy the data between search string */
if (found > src) {
- memcpy (&d[i], src, found - src);
+ memcpy (d + i, src, found - src);
i += found - src;
}
/* copy replace string instead */
if (strlen (replace) > 0) {
- memcpy (&d[i], replace, strlen (replace));
+ memcpy (d + i, replace, strlen (replace));
i += strlen (replace);
}
src = found + strlen (search);
@@ -68,14 +81,15 @@ str_replace (gchar **dst, const gchar *search, const gchar *replace)
/* copy the rest */
if (src) {
- memcpy (&d[i], src, strlen (src));
+ memcpy (d + i, src, strlen (src));
i += strlen (src);
}
d[i] = 0x0;
/* return fixed string */
g_free (*dst);
- *dst = g_strdup (&d[0]);
+ *dst = g_strdup (d);
+ g_free (d);
}
@@ -170,24 +184,29 @@ make_string (const gchar *substr, int count)
void
fix_entities (gchar **str)
{
- static gchar d[REPLACE_MAX_LENGTH];
+ gchar *d;
gchar *src;
gchar *found;
gchar *scan;
int i;
+ int alloc_size;
+ int used;
- /* TODO: add range checking */
if (! *str || strstr (*str, "&") == NULL)
return;
i = 0;
src = *str;
+ used = strlen (src) + 1;
+ alloc_size = ((used / STRING_ALLOC_SIZE) + 1) * STRING_ALLOC_SIZE;
+ d = g_malloc (alloc_size);
+
while (strstr (src, "&")) {
found = strstr (src, "&");
/* copy the data between search string */
- memcpy (&d[i], src, found - src + 1);
+ memcpy (d + i, src, found - src + 1);
i += found - src + 1;
/* scroll to next whitespace */
@@ -204,7 +223,12 @@ fix_entities (gchar **str)
}
else {
/* replace with &amp; */
- memcpy (&d[i], "amp;", 4);
+ used += 4;
+ if (used > alloc_size) {
+ alloc_size = ((used / STRING_ALLOC_SIZE) + 1) * STRING_ALLOC_SIZE;
+ d = g_realloc (d, alloc_size);
+ }
+ memcpy (d + i, "amp;", 4);
i += 4;
}
src = found + 1;
@@ -212,14 +236,15 @@ fix_entities (gchar **str)
/* copy the rest */
if (src) {
- memcpy (&d[i], src, strlen (src));
+ memcpy (d + i, src, strlen (src));
i += strlen (src);
}
d[i] = 0x0;
/* return fixed string */
g_free (*str);
- *str = g_strdup (&d[0]);
+ *str = g_strdup (d);
+ g_free (d);
}