diff --git a/src/misc.c b/src/misc.c index 6251d2d6..69a43017 100644 --- a/src/misc.c +++ b/src/misc.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -258,12 +259,33 @@ safe_hextou64(const char *str, uint64_t *val) /* Key/value functions */ +struct keyval * +keyval_alloc(void) +{ + struct keyval *kv; + + kv = (struct keyval *)malloc(sizeof(struct keyval)); + if (!kv) + { + DPRINTF(E_LOG, L_MISC, "Out of memory for keyval alloc\n"); + + return NULL; + } + + memset(kv, 0, sizeof(struct keyval)); + + return kv; +} + int keyval_add_size(struct keyval *kv, const char *name, const char *value, size_t size) { struct onekeyval *okv; const char *val; + if (!kv) + return -1; + /* Check for duplicate key names */ val = keyval_get(kv, name); if (val) @@ -330,6 +352,9 @@ keyval_remove(struct keyval *kv, const char *name) struct onekeyval *okv; struct onekeyval *pokv; + if (!kv) + return; + for (pokv = NULL, okv = kv->head; okv; pokv = okv, okv = okv->next) { if (strcasecmp(okv->name, name) == 0) @@ -358,6 +383,9 @@ keyval_get(struct keyval *kv, const char *name) { struct onekeyval *okv; + if (!kv) + return NULL; + for (okv = kv->head; okv; okv = okv->next) { if (strcasecmp(okv->name, name) == 0) @@ -373,6 +401,9 @@ keyval_clear(struct keyval *kv) struct onekeyval *hokv; struct onekeyval *okv; + if (!kv) + return; + hokv = kv->head; for (okv = hokv; hokv; okv = hokv) @@ -388,6 +419,47 @@ keyval_clear(struct keyval *kv) kv->tail = NULL; } +void +keyval_sort(struct keyval *kv) +{ + struct onekeyval *head; + struct onekeyval *okv; + struct onekeyval *sokv; + + if (!kv) + return; + + head = kv->head; + for (okv = kv->head; okv; okv = okv->next) + { + okv->sort = NULL; + for (sokv = kv->head; sokv; sokv = sokv->next) + { + // We try to find a name which is greater than okv->name + // but less than our current candidate (okv->sort->name) + if ( (strcmp(sokv->name, okv->name) > 0) && + ((okv->sort == NULL) || (strcmp(sokv->name, okv->sort->name) < 0)) ) + okv->sort = sokv; + } + + // Find smallest name, which will be the new head + if (strcmp(okv->name, head->name) < 0) + head = okv; + } + + while ((okv = kv->head)) + { + kv->head = okv->next; + okv->next = okv->sort; + } + + kv->head = head; + for (okv = kv->head; okv; okv = okv->next) + kv->tail = okv; + + DPRINTF(E_DBG, L_MISC, "Keyval sorted. New head: %s. New tail: %s.\n", kv->head->name, kv->tail->name); +} + char * m_realpath(const char *pathname) @@ -445,6 +517,43 @@ unicode_fixup_string(char *str) return (char *)ret; } +char * +trimwhitespace(const char *str) +{ + char *ptr; + char *start; + char *out; + + if (!str) + return NULL; + + // Find the beginning + while (isspace(*str)) + str++; + + if (*str == 0) // All spaces? + return strdup(""); + + // Make copy, because we will need to insert a null terminator + start = strdup(str); + if (!start) + return NULL; + + // Find the end + ptr = start + strlen(start) - 1; + while (ptr > start && isspace(*ptr)) + ptr--; + + // Insert null terminator + *(ptr+1) = 0; + + out = strdup(start); + + free(start); + + return out; +} + uint32_t djb_hash(void *data, size_t len) { diff --git a/src/misc.h b/src/misc.h index 1207df5b..500c0a88 100644 --- a/src/misc.h +++ b/src/misc.h @@ -12,6 +12,7 @@ struct onekeyval { char *value; struct onekeyval *next; + struct onekeyval *sort; }; struct keyval { @@ -40,6 +41,9 @@ safe_hextou64(const char *str, uint64_t *val); /* Key/value functions */ +struct keyval * +keyval_alloc(void); + int keyval_add(struct keyval *kv, const char *name, const char *value); @@ -55,6 +59,9 @@ keyval_get(struct keyval *kv, const char *name); void keyval_clear(struct keyval *kv); +void +keyval_sort(struct keyval *kv); + char * m_realpath(const char *pathname); @@ -62,6 +69,9 @@ m_realpath(const char *pathname); char * unicode_fixup_string(char *str); +char * +trimwhitespace(const char *str); + uint32_t djb_hash(void *data, size_t len);