Add trimwhitespace(), keyval sorting and alloc to misc functions

- features required by the LastFM module
This commit is contained in:
ejurgensen 2014-08-15 22:56:39 +02:00
parent d5efc2dcb3
commit 21cf3ab7d3
2 changed files with 119 additions and 0 deletions

View File

@ -28,6 +28,7 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <stdint.h>
#include <limits.h>
@ -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)
{

View File

@ -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);