From a4adf79a7cfd73612283ff14297e1ff94cc98f8e Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Sat, 14 Sep 2013 23:24:51 +0100 Subject: [PATCH] idnode prop: new API for specifying lists This is to avoid the need for string processing within the C code to combine and split lists from CSV strings. --- src/prop.c | 156 ++++++++++++++++++++++++++++------------------------- src/prop.h | 2 +- 2 files changed, 85 insertions(+), 73 deletions(-) diff --git a/src/prop.c b/src/prop.c index 0a2fd4ed..dc3e679b 100644 --- a/src/prop.c +++ b/src/prop.c @@ -58,11 +58,24 @@ prop_find(const property_t *p, const char *id) */ int prop_write_values - (void *obj, const property_t *pl, htsmsg_t *m, int optmask, htsmsg_t *updated) + (void *obj, const property_t *pl, htsmsg_t *m, int optmask, + htsmsg_t *updated) { int save, save2 = 0; htsmsg_field_t *f; const property_t *p; + void *cur; + const void *new; + double dbl; + int i; + uint32_t u32; + uint16_t u16; +#define PROP_UPDATE(v, t)\ + new = &v;\ + if (!p->set && (*((t*)cur) != *((t*)new))) {\ + save = 1;\ + *((t*)cur) = *((t*)new);\ + } (void)0 if (!pl) return 0; @@ -75,74 +88,67 @@ prop_write_values /* Write */ save = 0; - void *v = obj + p->off; + cur = obj + p->off; + new = NULL; - switch (p->type) { + /* List */ + if (p->islist) + new = htsmsg_field_get_list(f); + + /* Singular */ + else { + switch (p->type) { case PT_BOOL: { - int *val = v, tmp; - if (!htsmsg_field_get_bool(f, &tmp)) - if (*val != tmp) { - *val = tmp; - save = 1; - } + if (htsmsg_field_get_bool(f, &i)) + continue; + PROP_UPDATE(i, int); break; } case PT_INT: { - uint32_t tmp; - int *val = v; - if (!htsmsg_field_get_u32(f, &tmp)) - if (*val != (int)tmp) { - *val = (int)tmp; - save = 1; - } + if (htsmsg_field_get_u32(f, &u32)) + continue; + i = u32; + PROP_UPDATE(i, int); break; } case PT_U16: { - uint32_t tmp; - uint16_t *val = v; - if (!htsmsg_field_get_u32(f, &tmp)) - if (*val != (uint16_t)tmp) { - *val = (uint16_t)tmp; - save = 1; - } + if (htsmsg_field_get_u32(f, &u32)) + continue; + u16 = (uint16_t)u32; + PROP_UPDATE(u16, uint16_t); break; } case PT_U32: { - uint32_t tmp; - uint32_t *val = v; - if (!htsmsg_field_get_u32(f, &tmp)) - if (*val != tmp) { - *val = tmp; - save = 1; - } + if (htsmsg_field_get_u32(f, &u32)) + continue; + PROP_UPDATE(u32, uint32_t); break; } case PT_DBL: { - double tmp; - double *val = v; - if (!htsmsg_field_get_dbl(f, &tmp)) - if (*val != tmp) { - *val = tmp; - save = 1; - } + if (htsmsg_field_get_dbl(f, &dbl)) + continue; + PROP_UPDATE(dbl, double); break; } case PT_STR: { - char **val = v; - const char *tmp = htsmsg_field_get_str(f); - if (tmp) { - if(p->set != NULL) - save |= p->set(obj, tmp); - else if (strcmp(*val ?: "", tmp)) { - free(*val); - *val = strdup(tmp); - save = 1; - } + char **str = cur; + if (!(new = htsmsg_field_get_str(f))) + continue; + if (!p->set && strcmp((*str) ?: "", new)) { + free(*str); + *str = strdup(new); + save = 1; } break; } + } } + /* Setter */ + if (p->set && new) + save = p->set(obj, new); + + /* Updated */ if (save) { save2 = 1; if (p->notify) @@ -151,6 +157,7 @@ prop_write_values htsmsg_set_u32(updated, p->id, 1); } } +#undef PROP_UPDATE return save2; } @@ -163,7 +170,8 @@ prop_write_values */ static void prop_read_value - (void *obj, const property_t *p, htsmsg_t *m, const char *name, int optmask, htsmsg_t *inc) + (void *obj, const property_t *p, htsmsg_t *m, const char *name, + int optmask, htsmsg_t *inc) { const char *s; const void *val = obj + p->off; @@ -179,29 +187,33 @@ prop_read_value if (p->get) val = p->get(obj); - /* Read */ - switch(p->type) { - case PT_BOOL: - htsmsg_add_bool(m, name, *(int *)val); - break; - case PT_INT: - htsmsg_add_s64(m, name, *(int *)val); - break; - case PT_U32: - htsmsg_add_u32(m, name, *(uint32_t *)val); - break; - case PT_U16: - htsmsg_add_u32(m, name, *(uint16_t *)val); - break; - case PT_STR: - s = *(const char **)val; - if(s != NULL) { - htsmsg_add_str(m, name, s); + /* List */ + if (p->islist) + htsmsg_add_msg(m, name, (htsmsg_t*)val); + + /* Single */ + else { + switch(p->type) { + case PT_BOOL: + htsmsg_add_bool(m, name, *(int *)val); + break; + case PT_INT: + htsmsg_add_s64(m, name, *(int *)val); + break; + case PT_U32: + htsmsg_add_u32(m, name, *(uint32_t *)val); + break; + case PT_U16: + htsmsg_add_u32(m, name, *(uint16_t *)val); + break; + case PT_STR: + if ((s = *(const char **)val)) + htsmsg_add_str(m, name, s); + break; + case PT_DBL: + htsmsg_add_dbl(m, name, *(double*)val); + break; } - break; - case PT_DBL: - htsmsg_add_dbl(m, name, *(double*)val); - break; } } @@ -238,6 +250,8 @@ prop_serialize(void *obj, const property_t *pl, htsmsg_t *msg, int optmask, htsm htsmsg_add_str(m, "id", pl->id); htsmsg_add_str(m, "caption", pl->name); htsmsg_add_str(m, "type", val2str(pl->type, typetab) ?: "unknown"); + if (pl->islist) + htsmsg_add_u32(m, "list", 1); /* Options */ if (pl->opts & PO_RDONLY) @@ -246,8 +260,6 @@ prop_serialize(void *obj, const property_t *pl, htsmsg_t *msg, int optmask, htsm htsmsg_add_u32(m, "nosave", 1); if (pl->opts & PO_WRONCE) htsmsg_add_u32(m, "wronce", 1); - if (pl->opts & PO_MULTI) - htsmsg_add_u32(m, "multi", 1); /* Enum list */ if (pl->list) diff --git a/src/prop.h b/src/prop.h index f08d0855..995cd921 100644 --- a/src/prop.h +++ b/src/prop.h @@ -43,7 +43,6 @@ typedef enum { #define PO_RDONLY 0x01 // Property is read-only #define PO_NOSAVE 0x02 // Property is transient (not saved) #define PO_WRONCE 0x04 // Property is write-once (i.e. on creation) -#define PO_MULTI 0x08 // Multi-select /* * Property definition @@ -52,6 +51,7 @@ typedef struct property { const char *id; ///< Property Key const char *name; ///< Textual description prop_type_t type; ///< Type + int islist; ///< Is a list size_t off; ///< Offset into object int opts; ///< Options