-/* $Id$ */
-
/***
This file is part of avahi.
-
+
avahi is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
-
+
avahi is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public
License along with avahi; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
if (!(n = avahi_malloc(sizeof(AvahiStringList) + size)))
return NULL;
-
+
n->next = l;
n->size = size;
AvahiStringList *avahi_string_list_add_arbitrary(AvahiStringList *l, const uint8_t*text, size_t size) {
AvahiStringList *n;
- assert(text);
+ assert(size == 0 || text);
if (!(n = avahi_string_list_add_anonymous(l, size)))
return NULL;
int avahi_string_list_parse(const void* data, size_t size, AvahiStringList **ret) {
const uint8_t *c;
- AvahiStringList *r;
-
+ AvahiStringList *r = NULL;
+
assert(data);
assert(ret);
- r = NULL;
-
c = data;
while (size > 0) {
size_t k;
-
+
k = *(c++);
size--;
if (k > 0) { /* Ignore empty strings */
AvahiStringList *n;
- if (!(n = avahi_string_list_add_arbitrary(r, c, k)))
+ if (!(n = avahi_string_list_add_arbitrary(r, c, k)))
goto fail; /* OOM */
r = n;
}
-
+
c += k;
size -= k;
}
*ret = r;
-
+
return 0;
fail:
- avahi_string_list_free(*ret);
+ avahi_string_list_free(r);
return -1;
}
return NULL;
l = avahi_string_list_reverse(l);
-
+
for (n = l; n; n = n->next) {
if (n != l)
*(e++) = ' ';
}
l = avahi_string_list_reverse(l);
-
+
*e = 0;
return t;
size_t used = 0;
if (data) {
-
- if (l) {
- uint8_t *c;
- AvahiStringList *n;
-
- l = avahi_string_list_reverse(l);
- c = data;
-
- for (n = l; n; n = n->next) {
- size_t k;
- if (size < 1)
- break;
-
- k = n->size;
- if (k > 255)
- k = 255;
-
- if (k > size-1)
- k = size-1;
-
- *(c++) = k;
- memcpy(c, n->text, k);
- c += k;
-
- used += 1+ k;
- }
-
- l = avahi_string_list_reverse(l);
-
- } else {
+ AvahiStringList *n;
+ uint8_t *c;
+
+ l = avahi_string_list_reverse(l);
+ c = data;
+
+ for (n = l; size > 1 && n; n = n->next) {
+ size_t k;
+
+ if ((k = n->size) == 0)
+ /* Skip empty strings */
+ continue;
+
+ if (k > 255)
+ /* Truncate strings at 255 characters */
+ k = 255;
+
+ if (k > size-1)
+ /* Make sure this string fits in */
+ k = size-1;
+
+ *(c++) = (uint8_t) k;
+ memcpy(c, n->text, k);
+ c += k;
+
+ used += 1 + k;
+ size -= 1 + k;
+ }
+
+ l = avahi_string_list_reverse(l);
+
+ if (used == 0 && size > 0) {
/* Empty lists are treated specially. To comply with
* section 6.1 of the DNS-SD spec, we return a single
* empty string (i.e. a NUL byte)*/
- if (size > 0) {
- *(uint8_t*) data = 0;
- used = 1;
- }
-
+ *(uint8_t*) data = 0;
+ used = 1;
}
-
+
} else {
AvahiStringList *n;
- if (!l)
- used = 1;
- else {
-
- for (n = l; n; n = n->next) {
- size_t k;
-
- k = n->size;
- if (k > 255)
- k = 255;
-
- used += 1+k;
- }
+ for (n = l; n; n = n->next) {
+ size_t k;
+
+ if ((k = n->size) == 0)
+ continue;
+
+ if (k > 255)
+ k = 255;
+
+ used += 1+k;
}
+
+ if (used == 0)
+ used = 1;
}
return used;
va_start(va, r);
r = avahi_string_list_add_many_va(r, va);
va_end(va);
-
+
return r;
}
AvahiStringList *r = NULL;
for (; l; l = l->next)
- r = avahi_string_list_add_arbitrary(r, l->text, l->size);
+ if (!(r = avahi_string_list_add_arbitrary(r, l->text, l->size))) {
+ avahi_string_list_free(r);
+ return NULL;
+ }
return avahi_string_list_reverse(r);
}
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)))
for (;;) {
int n;
AvahiStringList *nr;
-
- n = vsnprintf((char*) r->text, len+1, format, va);
+ va_list va2;
+
+ va_copy(va2, va);
+ n = vsnprintf((char*) r->text, len, format, va2);
+ va_end(va2);
if (n >= 0 && n < (int) len)
break;
r = nr;
}
-
r->next = l;
- r->size = strlen((char*) r->text);
+ 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;
+ return l;
}
AvahiStringList *avahi_string_list_find(AvahiStringList *l, const char *key) {
size_t n;
-
+
assert(key);
n = strlen(key);
return avahi_string_list_add(l, key);
n = strlen(key);
-
+
if (!(l = avahi_string_list_add_anonymous(l, n + 1 + size)))
return NULL;
int avahi_string_list_get_pair(AvahiStringList *l, char **key, char **value, size_t *size) {
char *e;
-
+
assert(l);
if (!(e = memchr(l->text, '=', l->size))) {
- if (key)
+ if (key)
if (!(*key = avahi_strdup((char*) l->text)))
return -1;
return -1;
e++; /* Advance after '=' */
-
+
n = l->size - (e - (char*) l->text);
-
+
if (value) {
if (!(*value = avahi_memdup(e, n+1))) {
AvahiStringList *f;
char *value = NULL, *end = NULL;
uint32_t ret;
-
+
if (!(f = avahi_string_list_find(l, AVAHI_SERVICE_COOKIE)))
return AVAHI_SERVICE_COOKIE_INVALID;
}
avahi_free(value);
-
+
return ret;
}