#include <string.h>
#include <stdarg.h>
+#include <assert.h>
+#include <stdio.h>
#include "strlst.h"
+#include "malloc.h"
-AvahiStringList *avahi_string_list_add_arbitrary(AvahiStringList *l, const guint8*text, guint size) {
+AvahiStringList*avahi_string_list_add_anonymous(AvahiStringList *l, size_t size) {
AvahiStringList *n;
- g_assert(text);
-
- n = g_malloc(sizeof(AvahiStringList) + size);
- n->next = l;
- memcpy(n->text, text, n->size = size);
+ if (!(n = avahi_malloc(sizeof(AvahiStringList) + size)))
+ return NULL;
+ n->next = l;
+ n->size = size;
+
+ /* NUL terminate strings, just to make sure */
+ n->text[size] = 0;
+
return n;
}
-AvahiStringList *avahi_string_list_add(AvahiStringList *l, const gchar *text) {
- g_assert(text);
+AvahiStringList *avahi_string_list_add_arbitrary(AvahiStringList *l, const uint8_t*text, size_t size) {
+ AvahiStringList *n;
+
+ assert(text);
+
+ if (!(n = avahi_string_list_add_anonymous(l, size)))
+ return NULL;
+
+ if (size > 0)
+ memcpy(n->text, text, size);
- return avahi_string_list_add_arbitrary(l, (const guint8*) text, strlen(text));
+ return n;
}
-AvahiStringList *avahi_string_list_parse(gconstpointer data, guint size) {
+AvahiStringList *avahi_string_list_add(AvahiStringList *l, const char *text) {
+ assert(text);
+
+ return avahi_string_list_add_arbitrary(l, (const uint8_t*) text, strlen(text));
+}
+
+AvahiStringList *avahi_string_list_parse(const void* data, size_t size) {
AvahiStringList *r = NULL;
- const guint8 *c;
- g_assert(data);
+ const uint8_t *c;
+
+ assert(data);
c = data;
for (;;) {
- guint k;
+ size_t k;
if (size < 1)
break;
while (l) {
n = l->next;
- g_free(l);
+ avahi_free(l);
l = n;
}
}
-static AvahiStringList* string_list_reverse(AvahiStringList *l) {
+AvahiStringList* avahi_string_list_reverse(AvahiStringList *l) {
AvahiStringList *r = NULL, *n;
while (l) {
return r;
}
-gchar* avahi_string_list_to_string(AvahiStringList *l) {
+char* avahi_string_list_to_string(AvahiStringList *l) {
AvahiStringList *n;
- guint s = 0;
- gchar *t, *e;
+ size_t s = 0;
+ char *t, *e;
- l = string_list_reverse(l);
-
for (n = l; n; n = n->next) {
if (n != l)
s ++;
s += n->size+2;
}
- t = e = g_new(gchar, s+1);
+ if (!(t = e = avahi_new(char, s+1)))
+ return NULL;
+ l = avahi_string_list_reverse(l);
+
for (n = l; n; n = n->next) {
if (n != l)
*(e++) = ' ';
*(e++) = '"';
- strncpy(e, (gchar*) n->text, n->size);
+ strncpy(e, (char*) n->text, n->size);
e[n->size] = 0;
e = strchr(e, 0);
*(e++) = '"';
- g_assert(e);
+ assert(e);
}
- l = string_list_reverse(l);
+ l = avahi_string_list_reverse(l);
*e = 0;
return t;
}
-guint avahi_string_list_serialize(AvahiStringList *l, gpointer data, guint size) {
- guint used = 0;
+size_t avahi_string_list_serialize(AvahiStringList *l, void *data, size_t size) {
+ size_t used = 0;
if (data) {
- guint8 *c;
+ uint8_t *c;
AvahiStringList *n;
- g_assert(data);
+ assert(data);
- l = string_list_reverse(l);
+ l = avahi_string_list_reverse(l);
c = data;
for (n = l; n; n = n->next) {
- guint k;
+ size_t k;
if (size < 1)
break;
used += 1+ k;
}
- l = string_list_reverse(l);
+ l = avahi_string_list_reverse(l);
} else {
AvahiStringList *n;
for (n = l; n; n = n->next) {
- guint k;
+ size_t k;
k = n->size;
if (k > 255)
return used;
}
-gboolean avahi_string_list_equal(const AvahiStringList *a, const AvahiStringList *b) {
+int avahi_string_list_equal(const AvahiStringList *a, const AvahiStringList *b) {
for (;;) {
if (!a && !b)
- return TRUE;
+ return 1;
if (!a || !b)
- return FALSE;
+ return 0;
if (a->size != b->size)
- return FALSE;
+ return 0;
if (a->size != 0 && memcmp(a->text, b->text, a->size) != 0)
- return FALSE;
+ return 0;
a = a->next;
b = b->next;
}
AvahiStringList *avahi_string_list_add_many_va(AvahiStringList *r, va_list va) {
- const gchar *txt;
+ const char *txt;
- while ((txt = va_arg(va, const gchar*)))
+ while ((txt = va_arg(va, const char*)))
r = avahi_string_list_add(r, txt);
return r;
}
-
-AvahiStringList *avahi_string_list_new(const gchar *txt, ...) {
+AvahiStringList *avahi_string_list_new(const char *txt, ...) {
va_list va;
AvahiStringList *r = NULL;
for (; l; l = l->next)
r = avahi_string_list_add_arbitrary(r, l->text, l->size);
- return string_list_reverse(r);
+ return avahi_string_list_reverse(r);
+}
+
+AvahiStringList *avahi_string_list_new_from_array(const char *array[], int length) {
+ AvahiStringList *r = NULL;
+ int i;
+
+ assert(array);
+
+ for (i = 0; length >= 0 ? i < length : !!array[i]; i++)
+ r = avahi_string_list_add(r, array[i]);
+
+ return r;
+}
+
+unsigned avahi_string_list_length(const AvahiStringList *l) {
+ unsigned n = 0;
+
+ for (; l; l = l->next)
+ n++;
+
+ return n;
+}
+
+AvahiStringList *avahi_string_list_add_vprintf(AvahiStringList *l, const char *format, va_list va) {
+ size_t len = 80;
+ AvahiStringList *r;
+
+ assert(format);
+
+ if (!(r = avahi_malloc(sizeof(AvahiStringList) + len)))
+ return NULL;
+
+ for (;;) {
+ int n;
+ AvahiStringList *nr;
+
+ n = vsnprintf((char*) r->text, len+1, format, va);
+
+ if (n >= 0 && n < (int) len)
+ break;
+
+ if (n >= 0)
+ len = n+1;
+ else
+ len *= 2;
+
+ if (!(nr = avahi_realloc(r, sizeof(AvahiStringList) + len))) {
+ avahi_free(r);
+ return NULL;
+ }
+
+ r = nr;
+ }
+
+
+ r->next = l;
+ r->size = strlen((char*) r->text);
+
+ return r;
+}
+
+AvahiStringList *avahi_string_list_add_printf(AvahiStringList *l, const char *format, ...) {
+ va_list va;
+
+ assert(format);
+
+ va_start(va, format);
+ l = avahi_string_list_add_vprintf(l, format, va);
+ va_end(va);
+
+ return l;
+}
+
+AvahiStringList *avahi_string_list_find(AvahiStringList *l, const char *key) {
+ size_t n;
+
+ assert(key);
+ n = strlen(key);
+
+ for (; l; l = l->next) {
+ if (strcasecmp((char*) l->text, key) == 0)
+ return l;
+
+ if (strncasecmp((char*) l->text, key, n) == 0 && l->text[n] == '=')
+ return l;
+ }
+
+ return NULL;
+}
+
+AvahiStringList *avahi_string_list_add_pair(AvahiStringList *l, const char *key, const char *value) {
+ assert(key);
+
+ if (value)
+ return avahi_string_list_add_printf(l, "%s=%s", key, value);
+ else
+ return avahi_string_list_add(l, key);
+}
+
+AvahiStringList *avahi_string_list_add_pair_arbitrary(AvahiStringList *l, const char *key, const uint8_t *value, size_t size) {
+ size_t n;
+ assert(key);
+
+ if (!value)
+ return avahi_string_list_add(l, key);
+
+ n = strlen(key);
+
+ if (!(l = avahi_string_list_add_anonymous(l, n + 1 + size)))
+ return NULL;
+
+ memcpy(l->text, key, n);
+ l->text[n] = '=';
+ memcpy(l->text + n + 1, value, size);
+
+ return l;
+}
+
+
+int avahi_string_list_get_pair(AvahiStringList *l, char **key, char **value, size_t *size) {
+ char *e;
+
+ assert(l);
+ assert(key);
+
+ if (!(e = memchr(l->text, '=', l->size))) {
+
+ if (!(*key = avahi_strdup((char*) l->text)))
+ return -1;
+
+ if (value)
+ *value = NULL;
+
+ if (size)
+ *size = 0;
+
+ } else {
+ size_t n;
+
+ if (!(*key = avahi_strndup((char*) l->text, e - (char *) l->text)))
+ return -1;
+
+ e++; /* Advance after '=' */
+
+ n = l->size - (e - (char*) l->text);
+
+ if (value) {
+
+ if (!(*value = avahi_memdup(e, n+1))) {
+ avahi_free(*key);
+ return -1;
+ }
+
+ (*value)[n] = 0;
+ }
+
+ if (size)
+ *size = n;
+ }
+
+ return 0;
}