diff --git a/src/htsmsg.c b/src/htsmsg.c index 5c91c03d..055455bf 100644 --- a/src/htsmsg.c +++ b/src/htsmsg.c @@ -24,6 +24,7 @@ #include #include #include "htsmsg.h" +#include "misc/dbl.h" static void htsmsg_clear(htsmsg_t *msg); @@ -328,7 +329,14 @@ htsmsg_get_s64(htsmsg_t *msg, const char *name, int64_t *s64p) if((f = htsmsg_field_find(msg, name)) == NULL) return HTSMSG_ERR_FIELD_NOT_FOUND; + + return htsmsg_field_get_s64(f, s64p); +} +int +htsmsg_field_get_s64 + (htsmsg_field_t *f, int64_t *s64p) +{ switch(f->hmf_type) { default: return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; @@ -352,11 +360,50 @@ htsmsg_get_s64(htsmsg_t *msg, const char *name, int64_t *s64p) /** * */ + +int +htsmsg_field_get_bool + ( htsmsg_field_t *f, int *boolp ) +{ + switch(f->hmf_type) { + default: + return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; + case HMF_STR: + if (!strcmp(f->hmf_str, "yes") || + !strcmp(f->hmf_str, "true") || + !strcmp(f->hmf_str, "on") || + !strcmp(f->hmf_str, "1")) + *boolp = 1; + else + *boolp = 0; + break; + case HMF_S64: + *boolp = f->hmf_s64 ? 1 : 0; + break; + case HMF_BOOL: + *boolp = f->hmf_bool; + break; + } + return 0; +} + +int +htsmsg_get_bool + (htsmsg_t *msg, const char *name, int *boolp) +{ + htsmsg_field_t *f; + + if((f = htsmsg_field_find(msg, name)) == NULL) + return HTSMSG_ERR_FIELD_NOT_FOUND; + + return htsmsg_field_get_bool(f, boolp); +} + int htsmsg_get_bool_or_default(htsmsg_t *msg, const char *name, int def) { - int64_t s64; - return htsmsg_get_s64(msg, name, &s64) ? def : s64; + int ret; + return htsmsg_get_bool(msg, name, &ret) ? def : ret; } @@ -390,6 +437,22 @@ htsmsg_get_u32(htsmsg_t *msg, const char *name, uint32_t *u32p) return 0; } +int +htsmsg_field_get_u32(htsmsg_field_t *f, uint32_t *u32p) +{ + int r; + int64_t s64; + + if ((r = htsmsg_field_get_s64(f, &s64))) + return r; + + if (s64 < 0 || s64 > 0xffffffffL) + return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; + + *u32p = s64; + return 0; +} + /** * */ @@ -443,14 +506,30 @@ htsmsg_get_dbl(htsmsg_t *msg, const char *name, double *dblp) if((f = htsmsg_field_find(msg, name)) == NULL) return HTSMSG_ERR_FIELD_NOT_FOUND; - - if(f->hmf_type != HMF_DBL) - return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; - - *dblp = f->hmf_dbl; - return 0; + + return htsmsg_field_get_dbl(f, dblp); } +int +htsmsg_field_get_dbl + ( htsmsg_field_t *f, double *dblp ) +{ + switch (f->hmf_type) { + case HMF_S64: + *dblp = (double)f->hmf_s64; + break; + case HMF_DBL: + *dblp = f->hmf_dbl; + break; + case HMF_STR: + *dblp = my_str2double(f->hmf_str, NULL); + // TODO: better safety checks? + break; + default: + return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; + } + return 0; +} /* * @@ -478,19 +557,29 @@ htsmsg_get_bin(htsmsg_t *msg, const char *name, const void **binp, const char * htsmsg_field_get_string(htsmsg_field_t *f) { - char buf[40]; + char buf[128]; switch(f->hmf_type) { default: return NULL; case HMF_STR: break; + case HMF_BOOL: + f->hmf_str = strdup(f->hmf_bool ? "true" : "false"); + f->hmf_type = HMF_STR; + f->hmf_flags |= HMF_ALLOCED; case HMF_S64: snprintf(buf, sizeof(buf), "%"PRId64, f->hmf_s64); f->hmf_str = strdup(buf); f->hmf_type = HMF_STR; f->hmf_flags |= HMF_ALLOCED; break; + case HMF_DBL: + snprintf(buf, sizeof(buf), "%lf", f->hmf_dbl); + f->hmf_str = strdup(buf); + f->hmf_type = HMF_STR; + f->hmf_flags |= HMF_ALLOCED; + break; } return f->hmf_str; } diff --git a/src/htsmsg.h b/src/htsmsg.h index 19ee2726..63ff6f8f 100644 --- a/src/htsmsg.h +++ b/src/htsmsg.h @@ -177,6 +177,8 @@ void htsmsg_add_binptr(htsmsg_t *msg, const char *name, const void *bin, */ int htsmsg_get_u32(htsmsg_t *msg, const char *name, uint32_t *u32p); +int htsmsg_field_get_u32(htsmsg_field_t *f, uint32_t *u32p); + /** * Get an integer as an signed 32 bit integer. * @@ -195,11 +197,17 @@ int htsmsg_get_s32(htsmsg_t *msg, const char *name, int32_t *s32p); */ int htsmsg_get_s64(htsmsg_t *msg, const char *name, int64_t *s64p); +int htsmsg_field_get_s64(htsmsg_field_t *f, int64_t *s64p); + /* * Return the field \p name as an s64. */ int64_t htsmsg_get_s64_or_default(htsmsg_t *msg, const char *name, int64_t def); +int htsmsg_field_get_bool(htsmsg_field_t *f, int *boolp); + +int htsmsg_get_bool(htsmsg_t *msg, const char *name, int *boolp); + int htsmsg_get_bool_or_default(htsmsg_t *msg, const char *name, int def); @@ -262,11 +270,19 @@ const char *htsmsg_get_str_multi(htsmsg_t *msg, ...) */ int htsmsg_get_dbl(htsmsg_t *msg, const char *name, double *dblp); +int htsmsg_field_get_dbl(htsmsg_field_t *f, double *dblp); + /** * Given the field \p f, return a string if it is of type string, otherwise * return NULL */ const char *htsmsg_field_get_string(htsmsg_field_t *f); +#define htsmsg_field_get_str(f) htsmsg_field_get_string(f) + +/** + * Get s64 from field + */ + /** * Return the field \p name as an u32. diff --git a/src/prop.c b/src/prop.c index 704849b2..4488a2e6 100644 --- a/src/prop.c +++ b/src/prop.c @@ -27,28 +27,6 @@ * Utilities * *************************************************************************/ -#define TO_FROM(x, y) ((x) << 16 | (y)) - -/* - * Bool conversion - */ -#if 0 -static int -str_to_bool(const char *s) -{ - if(s == NULL) - return 0; - int v = atoi(s); - if(v) - return 1; - if(!strcasecmp(s, "on") || - !strcasecmp(s, "true") || - !strcasecmp(s, "yes")) - return 1; - return 0; -} -#endif - /** * */ @@ -98,66 +76,71 @@ prop_write_values /* Write */ save = 0; void *v = obj + p->off; - switch(TO_FROM(p->type, f->hmf_type)) { - case TO_FROM(PT_BOOL, HMF_BOOL): { - int *val = v; - if (*val != f->hmf_bool) { - *val = f->hmf_bool; - save = 1; + + switch (p->type) { + case PT_BOOL: { + int *val = v, tmp; + if (!htsmsg_field_get_bool(f, &tmp)) + if (*val != tmp) { + *val = tmp; + save = 1; + } + break; } - break; - } - case TO_FROM(PT_BOOL, HMF_S64): { - int *val = v; - if (*val != !!f->hmf_s64) { - *val = !!f->hmf_s64; - save = 1; + 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; + } + break; } - break; - } - case TO_FROM(PT_INT, HMF_S64): { - int *val = v; - if (*val != f->hmf_s64) { - *val = f->hmf_s64; - save = 1; + 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; + } + break; } - break; - } - case TO_FROM(PT_U16, HMF_S64): { - uint16_t *val = v; - if (*val != f->hmf_s64) { - *val = f->hmf_s64; - save = 1; + case PT_U32: { + uint32_t tmp; + uint32_t *val = v; + if (!htsmsg_field_get_u32(f, &tmp)) + if (*val != tmp) { + *val = tmp; + save = 1; + } + break; } - break; - } - case TO_FROM(PT_U32, HMF_S64): { - uint32_t *val = v; - if (*val != f->hmf_s64) { - *val = f->hmf_s64; - save = 1; + case PT_DBL: { + double tmp; + double *val = v; + if (!htsmsg_field_get_dbl(f, &tmp)) + if (*val != tmp) { + *val = tmp; + save = 1; + } + break; } - break; - } - case TO_FROM(PT_STR, HMF_STR): { - char **val = v; - if(p->set != NULL) - save |= p->set(obj, f->hmf_str); - else if (strcmp(*val ?: "", f->hmf_str)) { - free(*val); - *val = strdup(f->hmf_str); - save = 1; + 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; + } + } + break; } - break; - } - case TO_FROM(PT_DBL, HMF_DBL): { - double *val = v; - if (*val != f->hmf_dbl) { - *val = f->hmf_dbl; - save = 1; - } - break; - } } if (save) {