summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 & */
- 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);
}