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.
This commit is contained in:
parent
1fe897492b
commit
a4adf79a7c
2 changed files with 85 additions and 73 deletions
156
src/prop.c
156
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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue