From: Jaroslav Kysela Date: Sat, 6 Jan 2018 15:36:46 +0000 (+0100) Subject: htsmsg: add more code for bin type support (conversion from hexa strings) X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4c3c047653effc546df19bbdf0252e115323c8a2;p=thirdparty%2Ftvheadend.git htsmsg: add more code for bin type support (conversion from hexa strings) --- diff --git a/src/htsmsg.c b/src/htsmsg.c index 735d191a3..78e863561 100644 --- a/src/htsmsg.c +++ b/src/htsmsg.c @@ -156,8 +156,10 @@ htsmsg_field_add(htsmsg_t *msg, const char *name, int type, int flags, size_t es if(esize) { if(type == HMF_STR) f->hmf_str = f->hmf_edata + nsize; - else if(type == HMF_BIN) + else if(type == HMF_BIN) { f->hmf_bin = f->hmf_edata + nsize; + f->hmf_binsize = esize; + } } f->hmf_type = type; @@ -457,6 +459,57 @@ htsmsg_set_str(htsmsg_t *msg, const char *name, const char *str) return htsmsg_field_set_str(f, str); } +/* + * + */ +int +htsmsg_field_set_bin(htsmsg_field_t *f, const void *bin, size_t len) +{ + if (f->hmf_type != HMF_BIN) + return 1; + if (f->hmf_flags & HMF_ALLOCED) { +#if ENABLE_SLOW_MEMORYINFO + memoryinfo_remove(&htsmsg_field_memoryinfo, f->hmf_binsize); +#endif + free((void *)f->hmf_bin); + } + else if (f->hmf_flags & HMF_INALLOCED) { + if (f->hmf_binsize >= len) { + memmove((char *)f->hmf_bin, bin, len); + f->hmf_binsize = len; + return 0; + } + f->hmf_flags &= ~HMF_INALLOCED; + } + f->hmf_flags |= HMF_ALLOCED; + f->hmf_bin = malloc(len); + f->hmf_binsize = len; + if (f->hmf_bin == NULL && len > 0) { + f->hmf_flags &= ~HMF_ALLOCED; + f->hmf_binsize = 0; + return 1; + } +#if ENABLE_SLOW_MEMORYINFO + memoryinfo_alloc(&htsmsg_field_memoryinfo, len); +#endif + return 0; +} + +/* + * + */ +int +htsmsg_field_set_bin_force(htsmsg_field_t *f, const void *bin, size_t len) +{ + if (f->hmf_type != HMF_BIN) { + htsmsg_field_data_destroy(f); + f->hmf_type = HMF_BIN; + f->hmf_bin = NULL; + f->hmf_binsize = 0; + } + return htsmsg_field_set_bin(f, bin, len); +} + /* * */ @@ -464,8 +517,6 @@ void htsmsg_add_bin(htsmsg_t *msg, const char *name, const void *bin, size_t len) { htsmsg_field_t *f = htsmsg_field_add(msg, name, HMF_BIN, HMF_NAME_INALLOCED, len); - f->hmf_bin = f->hmf_str; - f->hmf_binsize = len; f->hmf_flags |= HMF_INALLOCED; memcpy((void *)f->hmf_bin, bin, len); } @@ -773,26 +824,6 @@ htsmsg_field_get_dbl return 0; } -/* - * - */ -int -htsmsg_get_bin(htsmsg_t *msg, const char *name, const void **binp, - size_t *lenp) -{ - htsmsg_field_t *f; - - if((f = htsmsg_field_find(msg, name)) == NULL) - return HTSMSG_ERR_FIELD_NOT_FOUND; - - if(f->hmf_type != HMF_BIN) - return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; - - *binp = f->hmf_bin; - *lenp = f->hmf_binsize; - return 0; -} - /** * */ @@ -832,7 +863,57 @@ htsmsg_get_str(htsmsg_t *msg, const char *name) if((f = htsmsg_field_find(msg, name)) == NULL) return NULL; return htsmsg_field_get_string(f); +} + +/** + * + */ +int +htsmsg_field_get_bin(htsmsg_field_t *f, const void **binp, size_t *lenp) +{ + uint8_t *p; + size_t l; + int r; + + switch(f->hmf_type) { + default: + return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; + case HMF_STR: + l = strlen(f->hmf_str); + if (l % 2) + return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; + l /= 2; + p = malloc(l); + if (hex2bin(p, l, f->hmf_str)) { + free(p); + return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; + } + r = htsmsg_field_set_bin_force(f, p, l); + free(p); + if (r) + return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; + break; + case HMF_BIN: + break; + } + *binp = f->hmf_bin; + *lenp = f->hmf_binsize; + return 0; +} + +/* + * + */ +int +htsmsg_get_bin + (htsmsg_t *msg, const char *name, const void **binp, size_t *lenp) +{ + htsmsg_field_t *f; + + if((f = htsmsg_field_find(msg, name)) == NULL) + return HTSMSG_ERR_FIELD_NOT_FOUND; + return htsmsg_field_get_bin(f, binp, lenp); } /* diff --git a/src/htsmsg.h b/src/htsmsg.h index 265901c90..6daf11892 100644 --- a/src/htsmsg.h +++ b/src/htsmsg.h @@ -216,19 +216,23 @@ void htsmsg_add_dbl(htsmsg_t *msg, const char *name, double dbl); */ void htsmsg_add_msg_extname(htsmsg_t *msg, const char *name, htsmsg_t *sub); +/** + * Update an binary field + */ +int htsmsg_field_set_bin(htsmsg_field_t *f, const void *bin, size_t len); +int htsmsg_field_set_bin_force(htsmsg_field_t *f, const void *bin, size_t len); + /** * Add an binary field. The data is copied to a malloced storage */ -void htsmsg_add_bin(htsmsg_t *msg, const char *name, const void *bin, - size_t len); +void htsmsg_add_bin(htsmsg_t *msg, const char *name, const void *bin, size_t len); /** * Add an binary field. The data is not copied, instead the caller * is responsible for keeping the data valid for as long as the message * is around. */ -void htsmsg_add_binptr(htsmsg_t *msg, const char *name, const void *bin, - size_t len); +void htsmsg_add_binptr(htsmsg_t *msg, const char *name, const void *bin, size_t len); /** * Get an integer as an unsigned 32 bit integer. @@ -348,9 +352,13 @@ 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 + * Get a field of type 'bin'. + * + * @return HTSMSG_ERR_FIELD_NOT_FOUND - Field does not exist + * HTSMSG_ERR_CONVERSION_IMPOSSIBLE - Field is not an integer or + * out of range for the requested storage. */ - +int htsmsg_field_get_bin(htsmsg_field_t *f, const void **binp, size_t *lenp); /** * Return the field \p name as an u32.