*
* Author:
* Miguel de Icaza (miguel@novell.com)
+ * Aaron Bockover (abockover@novell.com)
*
* (C) 2006 Novell, Inc.
*
#include <stdio.h>
#include <glib.h>
-GString *
-g_string_new (const gchar *init)
-{
- GString *ret = g_new (GString, 1);
- int len, alloc;
-
- len = strlen (init);
- if (len < 15)
- alloc = 16;
- else
- alloc = len+1;
- ret->str = g_malloc (alloc);
- ret->len = len;
- ret->allocated_len = alloc;
- strcpy (ret->str, init);
-
- return ret;
+#define GROW_IF_NECESSARY(s,l) { \
+ if(s->len + l >= s->allocated_len) { \
+ s->allocated_len = (s->allocated_len + l + 16) * 2; \
+ s->str = g_realloc(s->str, s->allocated_len); \
+ } \
}
GString *
{
GString *ret = g_new (GString, 1);
- ret->str = g_malloc (len+1);
- ret->allocated_len = len + 1;
- ret->len = len;
+ ret->len = len < 0 ? strlen(init) : len;
+ ret->allocated_len = MAX(ret->len + 1, 16);
+ ret->str = g_malloc(ret->allocated_len);
+ memcpy(ret->str, init, ret->len);
+ ret->str[ret->len] = 0;
- memcpy (ret->str, init, len);
- ret->str [len] = 0;
-
return ret;
}
+GString *
+g_string_new (const gchar *init)
+{
+ return g_string_new_len(init, -1);
+}
+
GString *
g_string_sized_new (gsize default_size)
{
gchar *
g_string_free (GString *string, gboolean free_segment)
{
- char *data;
+ gchar *data;
+
g_return_val_if_fail (string != NULL, NULL);
data = string->str;
- if (free_segment)
- g_free (data);
- g_free (string);
-
- if (free_segment)
- return NULL;
- else
- return data;
+ g_free(string);
+ if(!free_segment) {
+ return data;
+ }
+
+ g_free(data);
+ return NULL;
}
GString *
-g_string_append (GString *string, const gchar *val)
+g_string_append_len (GString *string, const gchar *val, gssize len)
{
- int len, size;
- char *new;
-
- g_return_val_if_fail (string != NULL, NULL);
- g_return_val_if_fail (val != NULL, string);
-
- len = strlen (val);
- if ((string->len + len) < string->allocated_len){
- strcat (string->str, val);
- string->len += len;
- return string;
+ g_return_val_if_fail(string != NULL, NULL);
+ g_return_val_if_fail(val != NULL, string);
+
+ if(len < 0) {
+ len = strlen(val);
}
- size = (len + string->len + 16) * 2;
- new = g_malloc (size);
- memcpy (new, string->str, string->len);
- memcpy (new + string->len, val, len);
- g_free (string->str);
- string->str = new;
- string->allocated_len = size;
+
+ GROW_IF_NECESSARY(string, len);
+ memcpy(string->str + string->len, val, len);
string->len += len;
- new [string->len] = 0;
-
+ string->str[string->len] = 0;
+
return string;
}
+GString *
+g_string_append (GString *string, const gchar *val)
+{
+ g_return_val_if_fail(string != NULL, NULL);
+ g_return_val_if_fail(val != NULL, string);
+
+ return g_string_append_len(string, val, -1);
+}
+
GString *
g_string_append_c (GString *string, gchar c)
{
- gsize size;
- char *new;
-
- g_return_val_if_fail (string != NULL, NULL);
+ g_return_val_if_fail(string != NULL, NULL);
- if (string->len + 1 < string->allocated_len){
- string->str [string->len] = c;
- string->str [string->len+1] = 0;
- string->len++;
- return string;
- }
- size = (string->allocated_len + 16) * 2;
- new = g_malloc (size);
- memcpy (new, string->str, string->len);
- new [string->len] = c;
- new [string->len+1] = 0;
+ GROW_IF_NECESSARY(string, 1);
- g_free (string->str);
- string->allocated_len = size;
+ string->str[string->len] = c;
+ string->str[string->len + 1] = 0;
string->len++;
- string->str = new;
return string;
}
GString *
-g_string_append_len (GString *string, const gchar *val, gssize len)
+g_string_prepend (GString *string, const gchar *val)
{
- int size;
- char *new;
+ gssize len;
- g_return_val_if_fail (string != NULL, NULL);
+ g_return_val_if_fail (string != NULL, string);
g_return_val_if_fail (val != NULL, string);
- if (len < 0)
- return g_string_append (string, val);
-
- if ((string->len + len) < string->allocated_len){
- memcpy (string->str+string->len, val, len);
- string->len += len;
- return string;
- }
- size = (len + string->len + 16) * 2;
- new = g_malloc (size);
- memcpy (new, string->str, string->len);
- memcpy (new + string->len, val, len);
- g_free (string->str);
- string->str = new;
- string->allocated_len = size;
- string->len += len;
- new [string->len] = 0;
+
+ len = strlen (val);
+ GROW_IF_NECESSARY(string, len);
+ memmove(string->str + len, string->str, string->len + 1);
+ memcpy(string->str, val, len);
+
return string;
}
-
+
void
g_string_append_printf (GString *string, const gchar *format, ...)
{
g_return_val_if_fail (string != NULL, string);
/* Silent return */
- if (len < 0)
- return string;
-
- if (len >= string->len)
+ if (len < 0 || len >= string->len) {
return string;
- string->len = len;
- string->str [len] = 0;
- return string;
-}
-
-GString *
-g_string_prepend (GString *string, const gchar *val)
-{
- int vallen;
- g_return_val_if_fail (string != NULL, string);
- g_return_val_if_fail (val != NULL, string);
-
- vallen = strlen (val);
-
- if ((string->len + vallen + 1) < string->allocated_len){
- memmove (string->str+vallen, string->str, string->len+1);
- memcpy (string->str, val, vallen);
- } else {
- /*
- * Add some extra space, so we do not reallocate too often
- * maybe we should centralize this decision somewhere else.
- */
- char *new;
- int nl = MAX (string->len + vallen + 1, string->allocated_len);
- nl = nl < 8192 ? (nl * 3) : nl + 1024;
-
- new = malloc (nl);
- /* Failure */
- if (new == NULL) {
- g_error ("No more memory");
- return string;
- }
- strcpy (new, val);
- /* To cope with embedded nulls */
- memcpy (new + vallen, string->str, string->len);
- string->len = string->len + vallen;
- g_free (string->str);
- string->str = new;
- string->allocated_len = nl;
}
+ string->len = len;
+ string->str[len] = 0;
return string;
}
#define sfail(k,p) if (s->str [p] != k) { g_string_free (s,TRUE); return FAILED("Got %s, Failed at %d, expected '%c'", s->str, p, k);}
+RESULT
+test_append_speed()
+{
+ GString *s = g_string_new("");
+ gint i;
+
+ for(i = 0; i < 1024; i++) {
+ g_string_append(s, "x");
+ }
+
+ if(strlen (s->str) != 1024) {
+ return FAILED("Incorrect string size, got: %s %d",
+ s->str, strlen(s->str));
+ }
+
+ g_string_free (s, TRUE);
+
+ return OK;
+}
+
+RESULT
+test_append_c_speed()
+{
+ GString *s = g_string_new("");
+ gint i;
+
+ for(i = 0; i < 1024; i++) {
+ g_string_append_c(s, 'x');
+ }
+
+ if(strlen(s->str) != 1024) {
+ return FAILED("Incorrect string size, got: %s %d", s->str,
+ strlen(s->str));
+ }
+
+ g_string_free(s, TRUE);
+
+ return OK;
+}
+
RESULT
test_gstring ()
{
return FAILED("Did not copy correctly, got: %s", s->str+4);
}
- g_string_free (s, TRUE);
- s = g_string_new ("");
- for (i = 0; i < 1024; i++){
- g_string_append (s, "x");
- }
- if (strlen (s->str) != 1024){
- return FAILED("Incorrect string size, got: %s %d", s->str, strlen (s->str));
- }
g_string_free (s, TRUE);
s = g_string_new ("");
return OK;
}
-static char *
+RESULT
test_sized ()
{
GString *s = g_string_sized_new (20);
return NULL;
}
-static char *
+RESULT
test_truncate ()
{
GString *s = g_string_new ("0123456789");
return NULL;
}
-static char *
+RESULT
test_prepend ()
{
GString *s = g_string_new ("dingus");
return NULL;
}
-static char *
+RESULT
test_appendlen ()
{
GString *s = g_string_new ("");
}
static Test string_tests [] = {
+ {"append-speed", test_append_speed},
+ {"append_c-speed", test_append_c_speed},
{"constructors+append", test_gstring },
{"constructor-sized", test_sized },
{"truncate", test_truncate },