From ffda02123d2e421104932e2e15dccb9ae31a59da Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 13 May 2002 09:34:08 +0000 Subject: [PATCH] Added INTEGER64 support by Paul Davis --- include/conf.h | 6 ++ include/control.h | 3 + src/conf.c | 152 ++++++++++++++++++++++++++++++++++++++++-- src/control/control.c | 37 ++++++++++ 4 files changed, 192 insertions(+), 6 deletions(-) diff --git a/include/conf.h b/include/conf.h index 87ae3f7f..fe529f53 100644 --- a/include/conf.h +++ b/include/conf.h @@ -47,6 +47,8 @@ extern "C" { typedef enum _snd_config_type { /** Integer number */ SND_CONFIG_TYPE_INTEGER, + /** 64 bit Integer number */ + SND_CONFIG_TYPE_INTEGER64, /** Real number */ SND_CONFIG_TYPE_REAL, /** Character string */ @@ -98,12 +100,14 @@ int snd_config_copy(snd_config_t **dst, snd_config_t *src); int snd_config_make(snd_config_t **config, const char *key, snd_config_type_t type); int snd_config_make_integer(snd_config_t **config, const char *key); +int snd_config_make_integer64(snd_config_t **config, const char *key); int snd_config_make_real(snd_config_t **config, const char *key); int snd_config_make_string(snd_config_t **config, const char *key); int snd_config_make_pointer(snd_config_t **config, const char *key); int snd_config_make_compound(snd_config_t **config, const char *key, int join); int snd_config_imake_integer(snd_config_t **config, const char *key, const long value); +int snd_config_imake_integer64(snd_config_t **config, const char *key, const long long value); int snd_config_imake_real(snd_config_t **config, const char *key, const double value); int snd_config_imake_string(snd_config_t **config, const char *key, const char *ascii); int snd_config_imake_pointer(snd_config_t **config, const char *key, const void *ptr); @@ -112,12 +116,14 @@ snd_config_type_t snd_config_get_type(const snd_config_t *config); int snd_config_set_id(snd_config_t *config, const char *id); int snd_config_set_integer(snd_config_t *config, long value); +int snd_config_set_integer64(snd_config_t *config, long long value); int snd_config_set_real(snd_config_t *config, double value); int snd_config_set_string(snd_config_t *config, const char *value); int snd_config_set_ascii(snd_config_t *config, const char *ascii); int snd_config_set_pointer(snd_config_t *config, const void *ptr); int snd_config_get_id(const snd_config_t *config, const char **value); int snd_config_get_integer(const snd_config_t *config, long *value); +int snd_config_get_integer64(const snd_config_t *config, long long *value); int snd_config_get_real(const snd_config_t *config, double *value); int snd_config_get_ireal(const snd_config_t *config, double *value); int snd_config_get_string(const snd_config_t *config, const char **value); diff --git a/include/control.h b/include/control.h index b3001a3a..49ef4fbc 100644 --- a/include/control.h +++ b/include/control.h @@ -343,6 +343,9 @@ unsigned int snd_ctl_elem_info_get_count(const snd_ctl_elem_info_t *obj); long snd_ctl_elem_info_get_min(const snd_ctl_elem_info_t *obj); long snd_ctl_elem_info_get_max(const snd_ctl_elem_info_t *obj); long snd_ctl_elem_info_get_step(const snd_ctl_elem_info_t *obj); +long long snd_ctl_elem_info_get_min64(const snd_ctl_elem_info_t *obj); +long long snd_ctl_elem_info_get_max64(const snd_ctl_elem_info_t *obj); +long long snd_ctl_elem_info_get_step64(const snd_ctl_elem_info_t *obj); unsigned int snd_ctl_elem_info_get_items(const snd_ctl_elem_info_t *obj); void snd_ctl_elem_info_set_item(snd_ctl_elem_info_t *obj, unsigned int val); const char *snd_ctl_elem_info_get_item_name(const snd_ctl_elem_info_t *obj); diff --git a/src/conf.c b/src/conf.c index e00ab7c3..11822b4c 100644 --- a/src/conf.c +++ b/src/conf.c @@ -415,6 +415,7 @@ compound node.

#include #include #include +#include #include #include #include "local.h" @@ -426,6 +427,7 @@ struct _snd_config { snd_config_type_t type; union { long integer; + long long integer64; char *string; double real; const void *ptr; @@ -458,6 +460,18 @@ typedef struct { int ch; } input_t; +int safe_strtoll(const char *str, long long *val) +{ + long long v; + if (!*str) + return -EINVAL; + errno = 0; + if (sscanf(str, "%Ld", &v) != 1) + return -EINVAL; + *val = v; + return 0; +} + int safe_strtol(const char *str, long *val) { char *end; @@ -882,9 +896,9 @@ static int parse_value(snd_config_t **_n, snd_config_t *father, input_t *input, return 0; } if (err == 0 && ((s[0] >= '0' && s[0] <= '9') || s[0] == '-')) { - long i; + long long i; errno = 0; - err = safe_strtol(s, &i); + err = safe_strtoll(s, &i); if (err < 0) { double r; err = safe_strtod(s, &r); @@ -907,16 +921,22 @@ static int parse_value(snd_config_t **_n, snd_config_t *father, input_t *input, } else { free(s); if (n) { - if (n->type != SND_CONFIG_TYPE_INTEGER) { + if (n->type != SND_CONFIG_TYPE_INTEGER && n->type != SND_CONFIG_TYPE_INTEGER64) { SNDERR("%s is not an integer", *id); return -EINVAL; } } else { - err = _snd_config_make_add(&n, id, SND_CONFIG_TYPE_INTEGER, father); + if (i <= INT_MAX) + err = _snd_config_make_add(&n, id, SND_CONFIG_TYPE_INTEGER, father); + else + err = _snd_config_make_add(&n, id, SND_CONFIG_TYPE_INTEGER64, father); if (err < 0) return err; } - n->u.integer = i; + if (n->type == SND_CONFIG_TYPE_INTEGER) + n->u.integer = (long) i; + else + n->u.integer64 = i; *_n = n; return 0; } @@ -1291,6 +1311,9 @@ static int _snd_config_save_leaf(snd_config_t *n, snd_output_t *out, case SND_CONFIG_TYPE_INTEGER: snd_output_printf(out, "%ld", n->u.integer); break; + case SND_CONFIG_TYPE_INTEGER64: + snd_output_printf(out, "%Ld", n->u.integer64); + break; case SND_CONFIG_TYPE_REAL: snd_output_printf(out, "%-16g", n->u.real); break; @@ -1414,6 +1437,10 @@ int snd_config_get_type_ascii(const char *ascii, snd_config_type_t *type) *type = SND_CONFIG_TYPE_INTEGER; return 0; } + if (!strcmp(ascii, "integer64")) { + *type = SND_CONFIG_TYPE_INTEGER64; + return 0; + } if (!strcmp(ascii, "real")) { *type = SND_CONFIG_TYPE_REAL; return 0; @@ -1689,6 +1716,17 @@ int snd_config_make_integer(snd_config_t **config, const char *id) return snd_config_make(config, id, SND_CONFIG_TYPE_INTEGER); } +/** + * \brief Build an integer64 config node + * \param config Returned config node handle pointer + * \param id Node id + * \return 0 on success otherwise a negative error code + */ +int snd_config_make_integer64(snd_config_t **config, const char *id) +{ + return snd_config_make(config, id, SND_CONFIG_TYPE_INTEGER64); +} + /** * \brief Build a real config node * \param config Returned config node handle pointer @@ -1758,6 +1796,24 @@ int snd_config_imake_integer(snd_config_t **config, const char *id, const long v return 0; } +/** + * \brief Build an integer64 config node and use given initial value + * \param config Returned config node handle pointer + * \param id Node id + * \param value Initial value + * \return 0 on success otherwise a negative error code + */ +int snd_config_imake_integer64(snd_config_t **config, const char *id, const long long value) +{ + int err; + + err = snd_config_make(config, id, SND_CONFIG_TYPE_INTEGER64); + if (err < 0) + return err; + (*config)->u.integer64 = value; + return 0; +} + /** * \brief Build a real config node and use given initial value * \param config Returned config node handle pointer @@ -1837,6 +1893,21 @@ int snd_config_set_integer(snd_config_t *config, long value) return 0; } +/** + * \brief Change the value of an integer64 config node + * \param config Config node handle + * \param value Value + * \return 0 on success otherwise a negative error code + */ +int snd_config_set_integer64(snd_config_t *config, long long value) +{ + assert(config); + if (config->type != SND_CONFIG_TYPE_INTEGER64) + return -EINVAL; + config->u.integer64 = value; + return 0; +} + /** * \brief Change the value of a real config node * \param config Config node handle @@ -1909,6 +1980,15 @@ int snd_config_set_ascii(snd_config_t *config, const char *ascii) config->u.integer = i; } break; + case SND_CONFIG_TYPE_INTEGER64: + { + long long i; + int err = safe_strtoll(ascii, &i); + if (err < 0) + return err; + config->u.integer64 = i; + } + break; case SND_CONFIG_TYPE_REAL: { double d; @@ -1947,6 +2027,21 @@ int snd_config_get_integer(const snd_config_t *config, long *ptr) return 0; } +/** + * \brief Get the value of an integer64 config node + * \param config Config node handle + * \param ptr Returned value pointer + * \return 0 on success otherwise a negative error code + */ +int snd_config_get_integer64(const snd_config_t *config, long long *ptr) +{ + assert(config && ptr); + if (config->type != SND_CONFIG_TYPE_INTEGER64) + return -EINVAL; + *ptr = config->u.integer64; + return 0; +} + /** * \brief Get the value of a real config node * \param config Config node handle @@ -1968,7 +2063,7 @@ int snd_config_get_real(const snd_config_t *config, double *ptr) * \param ptr Returned value pointer * \return 0 on success otherwise a negative error code * - * Note: If the config type is integer, it is converted + * Note: If the config type is integer/integer64, it is converted * to the double type on the fly. */ int snd_config_get_ireal(const snd_config_t *config, double *ptr) @@ -1978,6 +2073,8 @@ int snd_config_get_ireal(const snd_config_t *config, double *ptr) *ptr = config->u.real; else if (config->type == SND_CONFIG_TYPE_INTEGER) *ptr = config->u.integer; + else if (config->type == SND_CONFIG_TYPE_INTEGER64) + *ptr = config->u.integer64; else return -EINVAL; return 0; @@ -2035,6 +2132,18 @@ int snd_config_get_ascii(const snd_config_t *config, char **ascii) *ascii = strdup(res); } break; + case SND_CONFIG_TYPE_INTEGER64: + { + char res[32]; + int err; + err = snprintf(res, sizeof(res), "%Li", config->u.integer64); + if (err < 0 || err == sizeof(res)) { + assert(0); + return -ENOMEM; + } + *ascii = strdup(res); + } + break; case SND_CONFIG_TYPE_REAL: { char res[32]; @@ -3054,6 +3163,14 @@ static int _snd_config_copy(snd_config_t *src, snd_config_set_integer(*dst, v); break; } + case SND_CONFIG_TYPE_INTEGER64: + { + long long v; + err = snd_config_get_integer64(src, &v); + assert(err >= 0); + snd_config_set_integer64(*dst, v); + break; + } case SND_CONFIG_TYPE_REAL: { double v; @@ -3124,6 +3241,16 @@ static int _snd_config_expand(snd_config_t *src, return err; break; } + case SND_CONFIG_TYPE_INTEGER64: + { + long long v; + err = snd_config_get_integer64(src, &v); + assert(err >= 0); + err = snd_config_imake_integer64(dst, id, v); + if (err < 0) + return err; + break; + } case SND_CONFIG_TYPE_REAL: { double v; @@ -3613,6 +3740,19 @@ static int parse_args(snd_config_t *subs, const char *str, snd_config_t *defs) err = snd_config_set_integer(sub, v); if (err < 0) goto _err; + } else if (strcmp(tmp, "integer64") == 0) { + long long v; + err = snd_config_make(&sub, var, SND_CONFIG_TYPE_INTEGER64); + if (err < 0) + goto _err; + err = safe_strtoll(val, &v); + if (err < 0) { + SNDERR("Parameter %s must be an integer", var); + goto _err; + } + err = snd_config_set_integer64(sub, v); + if (err < 0) + goto _err; } else if (strcmp(tmp, "real") == 0) { double v; err = snd_config_make(&sub, var, SND_CONFIG_TYPE_REAL); diff --git a/src/control/control.c b/src/control/control.c index 4281059e..7a65ce30 100644 --- a/src/control/control.c +++ b/src/control/control.c @@ -666,6 +666,7 @@ static const char *snd_ctl_elem_type_names[] = { TYPE(ENUMERATED), TYPE(BYTES), TYPE(IEC958), + TYPE(INTEGER64), }; static const char *snd_ctl_elem_iface_names[] = { @@ -1599,6 +1600,42 @@ long snd_ctl_elem_info_get_step(const snd_ctl_elem_info_t *obj) return obj->value.integer.step; } +/** + * \brief Get minimum value from a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/info + * \param obj CTL element id/info + * \return Minimum value + */ +long long snd_ctl_elem_info_get_min64(const snd_ctl_elem_info_t *obj) +{ + assert(obj); + assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER64); + return obj->value.integer64.min; +} + +/** + * \brief Get maximum value from a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/info + * \param obj CTL element id/info + * \return Maximum value + */ +long long snd_ctl_elem_info_get_max64(const snd_ctl_elem_info_t *obj) +{ + assert(obj); + assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER64); + return obj->value.integer64.max; +} + +/** + * \brief Get value step from a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/info + * \param obj CTL element id/info + * \return Step + */ +long long snd_ctl_elem_info_get_step64(const snd_ctl_elem_info_t *obj) +{ + assert(obj); + assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER64); + return obj->value.integer64.step; +} + /** * \brief Get number of items available from a #SND_CTL_ELEM_TYPE_ENUMERATED CTL element id/info * \param obj CTL element id/info -- 2.47.1